The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/kern_descrip.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: kern_descrip.c,v 1.131.2.1 2005/05/28 12:41:08 tron Exp $      */
    2 
    3 /*
    4  * Copyright (c) 1982, 1986, 1989, 1991, 1993
    5  *      The Regents of the University of California.  All rights reserved.
    6  * (c) UNIX System Laboratories, Inc.
    7  * All or some portions of this file are derived from material licensed
    8  * to the University of California by American Telephone and Telegraph
    9  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   10  * the permission of UNIX System Laboratories, Inc.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above copyright
   18  *    notice, this list of conditions and the following disclaimer in the
   19  *    documentation and/or other materials provided with the distribution.
   20  * 3. Neither the name of the University nor the names of its contributors
   21  *    may be used to endorse or promote products derived from this software
   22  *    without specific prior written permission.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   34  * SUCH DAMAGE.
   35  *
   36  *      @(#)kern_descrip.c      8.8 (Berkeley) 2/14/95
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: kern_descrip.c,v 1.131.2.1 2005/05/28 12:41:08 tron Exp $");
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/filedesc.h>
   45 #include <sys/kernel.h>
   46 #include <sys/vnode.h>
   47 #include <sys/proc.h>
   48 #include <sys/file.h>
   49 #include <sys/namei.h>
   50 #include <sys/socket.h>
   51 #include <sys/socketvar.h>
   52 #include <sys/stat.h>
   53 #include <sys/ioctl.h>
   54 #include <sys/fcntl.h>
   55 #include <sys/malloc.h>
   56 #include <sys/pool.h>
   57 #include <sys/syslog.h>
   58 #include <sys/unistd.h>
   59 #include <sys/resourcevar.h>
   60 #include <sys/conf.h>
   61 #include <sys/event.h>
   62 
   63 #include <sys/mount.h>
   64 #include <sys/sa.h>
   65 #include <sys/syscallargs.h>
   66 
   67 /*
   68  * Descriptor management.
   69  */
   70 struct filelist filehead;       /* head of list of open files */
   71 int             nfiles;         /* actual number of open files */
   72 POOL_INIT(file_pool, sizeof(struct file), 0, 0, 0, "filepl",
   73     &pool_allocator_nointr);
   74 POOL_INIT(cwdi_pool, sizeof(struct cwdinfo), 0, 0, 0, "cwdipl",
   75     &pool_allocator_nointr);
   76 POOL_INIT(filedesc0_pool, sizeof(struct filedesc0), 0, 0, 0, "fdescpl",
   77     &pool_allocator_nointr);
   78 
   79 /* Global file list lock */
   80 static struct simplelock filelist_slock = SIMPLELOCK_INITIALIZER;
   81 
   82 MALLOC_DEFINE(M_FILE, "file", "Open file structure");
   83 MALLOC_DEFINE(M_FILEDESC, "file desc", "Open file descriptor table");
   84 MALLOC_DEFINE(M_IOCTLOPS, "ioctlops", "ioctl data buffer");
   85 
   86 static __inline void    fd_used(struct filedesc *, int);
   87 static __inline void    fd_unused(struct filedesc *, int);
   88 static __inline int     find_next_zero(uint32_t *, int, u_int);
   89 int                     finishdup(struct proc *, int, int, register_t *);
   90 int                     find_last_set(struct filedesc *, int);
   91 int                     fcntl_forfs(int, struct proc *, int, void *);
   92 
   93 dev_type_open(filedescopen);
   94 
   95 const struct cdevsw filedesc_cdevsw = {
   96         filedescopen, noclose, noread, nowrite, noioctl,
   97         nostop, notty, nopoll, nommap, nokqfilter,
   98 };
   99 
  100 static __inline int
  101 find_next_zero(uint32_t *bitmap, int want, u_int bits)
  102 {
  103         int i, off, maxoff;
  104         uint32_t sub;
  105 
  106         if (want > bits)
  107                 return -1;
  108 
  109         off = want >> NDENTRYSHIFT;
  110         i = want & NDENTRYMASK;
  111         if (i) {
  112                 sub = bitmap[off] | ((u_int)~0 >> (NDENTRIES - i));
  113                 if (sub != ~0)
  114                         goto found;
  115                 off++;
  116         }
  117 
  118         maxoff = NDLOSLOTS(bits);
  119         while (off < maxoff) {
  120                 if ((sub = bitmap[off]) != ~0)
  121                         goto found;
  122                 off++;
  123         }
  124 
  125         return (-1);
  126 
  127  found:
  128         return (off << NDENTRYSHIFT) + ffs(~sub) - 1;
  129 }
  130 
  131 int
  132 find_last_set(struct filedesc *fd, int last)
  133 {
  134         int off, i;
  135         struct file **ofiles = fd->fd_ofiles;
  136         uint32_t *bitmap = fd->fd_lomap;
  137 
  138         off = (last - 1) >> NDENTRYSHIFT;
  139 
  140         while (off >= 0 && !bitmap[off])
  141                 off--;
  142 
  143         if (off < 0)
  144                 return (-1);
  145 
  146         i = ((off + 1) << NDENTRYSHIFT) - 1;
  147         if (i >= last)
  148                 i = last - 1;
  149 
  150         while (i > 0 && ofiles[i] == NULL)
  151                 i--;
  152 
  153         return (i);
  154 }
  155 
  156 static __inline void
  157 fd_used(struct filedesc *fdp, int fd)
  158 {
  159         u_int off = fd >> NDENTRYSHIFT;
  160 
  161         LOCK_ASSERT(simple_lock_held(&fdp->fd_slock));
  162         KDASSERT((fdp->fd_lomap[off] & (1 << (fd & NDENTRYMASK))) == 0);
  163 
  164         fdp->fd_lomap[off] |= 1 << (fd & NDENTRYMASK);
  165         if (fdp->fd_lomap[off] == ~0) {
  166                 KDASSERT((fdp->fd_himap[off >> NDENTRYSHIFT] &
  167                     (1 << (off & NDENTRYMASK))) == 0);
  168                 fdp->fd_himap[off >> NDENTRYSHIFT] |= 1 << (off & NDENTRYMASK);
  169         }
  170 
  171         if (fd > fdp->fd_lastfile)
  172                 fdp->fd_lastfile = fd;
  173 }
  174 
  175 static __inline void
  176 fd_unused(struct filedesc *fdp, int fd)
  177 {
  178         u_int off = fd >> NDENTRYSHIFT;
  179 
  180         LOCK_ASSERT(simple_lock_held(&fdp->fd_slock));
  181         if (fd < fdp->fd_freefile)
  182                 fdp->fd_freefile = fd;
  183 
  184         if (fdp->fd_lomap[off] == ~0) {
  185                 KDASSERT((fdp->fd_himap[off >> NDENTRYSHIFT] &
  186                     (1 << (off & NDENTRYMASK))) != 0);
  187                 fdp->fd_himap[off >> NDENTRYSHIFT] &=
  188                     ~(1 << (off & NDENTRYMASK));
  189         }
  190         KDASSERT((fdp->fd_lomap[off] & (1 << (fd & NDENTRYMASK))) != 0);
  191         fdp->fd_lomap[off] &= ~(1 << (fd & NDENTRYMASK));
  192 
  193 #ifdef DIAGNOSTIC
  194         if (fd > fdp->fd_lastfile)
  195                 panic("fd_unused: fd_lastfile inconsistent");
  196 #endif
  197         if (fd == fdp->fd_lastfile)
  198                 fdp->fd_lastfile = find_last_set(fdp, fd);
  199 }
  200 
  201 /*
  202  * Lookup the file structure corresponding to a file descriptor
  203  * and return it locked.
  204  * Note: typical usage is: `fp = fd_getfile(..); FILE_USE(fp);'
  205  * The locking strategy has been optimised for this case, i.e.
  206  * fd_getfile() returns the file locked while FILE_USE() will increment
  207  * the file's use count and unlock.
  208  */
  209 struct file *
  210 fd_getfile(struct filedesc *fdp, int fd)
  211 {
  212         struct file *fp;
  213 
  214         if ((u_int) fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL)
  215                 return (NULL);
  216 
  217         simple_lock(&fp->f_slock);
  218         if (FILE_IS_USABLE(fp) == 0) {
  219                 simple_unlock(&fp->f_slock);
  220                 return (NULL);
  221         }
  222 
  223         return (fp);
  224 }
  225 
  226 /*
  227  * System calls on descriptors.
  228  */
  229 
  230 /*
  231  * Duplicate a file descriptor.
  232  */
  233 /* ARGSUSED */
  234 int
  235 sys_dup(struct lwp *l, void *v, register_t *retval)
  236 {
  237         struct sys_dup_args /* {
  238                 syscallarg(int) fd;
  239         } */ *uap = v;
  240         struct file     *fp;
  241         struct filedesc *fdp;
  242         struct proc     *p;
  243         int             old, new, error;
  244 
  245         p = l->l_proc;
  246         fdp = p->p_fd;
  247         old = SCARG(uap, fd);
  248 
  249  restart:
  250         if ((fp = fd_getfile(fdp, old)) == NULL)
  251                 return (EBADF);
  252 
  253         FILE_USE(fp);
  254 
  255         if ((error = fdalloc(p, 0, &new)) != 0) {
  256                 if (error == ENOSPC) {
  257                         fdexpand(p);
  258                         FILE_UNUSE(fp, p);
  259                         goto restart;
  260                 }
  261                 FILE_UNUSE(fp, p);
  262                 return (error);
  263         }
  264 
  265         /* finishdup() will unuse the descriptors for us */
  266         return (finishdup(p, old, new, retval));
  267 }
  268 
  269 /*
  270  * Duplicate a file descriptor to a particular value.
  271  */
  272 /* ARGSUSED */
  273 int
  274 sys_dup2(struct lwp *l, void *v, register_t *retval)
  275 {
  276         struct sys_dup2_args /* {
  277                 syscallarg(int) from;
  278                 syscallarg(int) to;
  279         } */ *uap = v;
  280         struct file     *fp;
  281         struct filedesc *fdp;
  282         struct proc     *p;
  283         int             old, new, i, error;
  284 
  285         p = l->l_proc;
  286         fdp = p->p_fd;
  287         old = SCARG(uap, from);
  288         new = SCARG(uap, to);
  289 
  290  restart:
  291         if ((fp = fd_getfile(fdp, old)) == NULL)
  292                 return (EBADF);
  293 
  294         if ((u_int)new >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
  295             (u_int)new >= maxfiles) {
  296                 simple_unlock(&fp->f_slock);
  297                 return (EBADF);
  298         }
  299 
  300         if (old == new) {
  301                 simple_unlock(&fp->f_slock);
  302                 *retval = new;
  303                 return (0);
  304         }
  305 
  306         FILE_USE(fp);
  307 
  308         if (new >= fdp->fd_nfiles) {
  309                 if ((error = fdalloc(p, new, &i)) != 0) {
  310                         if (error == ENOSPC) {
  311                                 fdexpand(p);
  312                                 FILE_UNUSE(fp, p);
  313                                 goto restart;
  314                         }
  315                         FILE_UNUSE(fp, p);
  316                         return (error);
  317                 }
  318                 if (new != i)
  319                         panic("dup2: fdalloc");
  320         } else {
  321                 simple_lock(&fdp->fd_slock);
  322                 /*
  323                  * Mark `new' slot "used" only if it was empty.
  324                  */
  325                 if (fdp->fd_ofiles[new] == NULL)
  326                         fd_used(fdp, new);
  327                 simple_unlock(&fdp->fd_slock);
  328         }
  329 
  330         /*
  331          * finishdup() will close the file that's in the `new'
  332          * slot, if there's one there.
  333          */
  334 
  335         /* finishdup() will unuse the descriptors for us */
  336         return (finishdup(p, old, new, retval));
  337 }
  338 
  339 /*
  340  * The file control system call.
  341  */
  342 /* ARGSUSED */
  343 int
  344 sys_fcntl(struct lwp *l, void *v, register_t *retval)
  345 {
  346         struct sys_fcntl_args /* {
  347                 syscallarg(int)         fd;
  348                 syscallarg(int)         cmd;
  349                 syscallarg(void *)      arg;
  350         } */ *uap = v;
  351         struct filedesc *fdp;
  352         struct file     *fp;
  353         struct proc     *p;
  354         struct vnode    *vp;
  355         int             fd, i, tmp, error, flg, cmd, newmin;
  356         struct flock    fl;
  357 
  358         p = l->l_proc;
  359         fd = SCARG(uap, fd);
  360         cmd = SCARG(uap, cmd);
  361         fdp = p->p_fd;
  362         error = 0;
  363         flg = F_POSIX;
  364 
  365         switch (cmd) {
  366         case F_CLOSEM:
  367                 if (fd < 0)
  368                         return EBADF;
  369                 while (fdp->fd_lastfile >= fd)
  370                         fdrelease(p, fdp->fd_lastfile);
  371                 return 0;
  372 
  373         case F_MAXFD:
  374                 *retval = fdp->fd_lastfile;
  375                 return 0;
  376 
  377         default:
  378                 /* Handled below */
  379                 break;
  380         }
  381 
  382  restart:
  383         if ((fp = fd_getfile(fdp, fd)) == NULL)
  384                 return (EBADF);
  385 
  386         FILE_USE(fp);
  387 
  388         if ((cmd & F_FSCTL)) {
  389                 error = fcntl_forfs(fd, p, cmd, SCARG(uap, arg));
  390                 goto out;
  391         }
  392 
  393         switch (cmd) {
  394 
  395         case F_DUPFD:
  396                 newmin = (long)SCARG(uap, arg);
  397                 if ((u_int)newmin >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
  398                     (u_int)newmin >= maxfiles) {
  399                         error = EINVAL;
  400                         goto out;
  401                 }
  402                 if ((error = fdalloc(p, newmin, &i)) != 0) {
  403                         if (error == ENOSPC) {
  404                                 fdexpand(p);
  405                                 FILE_UNUSE(fp, p);
  406                                 goto restart;
  407                         }
  408                         goto out;
  409                 }
  410 
  411                 /* finishdup() will unuse the descriptors for us */
  412                 return (finishdup(p, fd, i, retval));
  413 
  414         case F_GETFD:
  415                 *retval = fdp->fd_ofileflags[fd] & UF_EXCLOSE ? 1 : 0;
  416                 break;
  417 
  418         case F_SETFD:
  419                 if ((long)SCARG(uap, arg) & 1)
  420                         fdp->fd_ofileflags[fd] |= UF_EXCLOSE;
  421                 else
  422                         fdp->fd_ofileflags[fd] &= ~UF_EXCLOSE;
  423                 break;
  424 
  425         case F_GETFL:
  426                 *retval = OFLAGS(fp->f_flag);
  427                 break;
  428 
  429         case F_SETFL:
  430                 tmp = FFLAGS((long)SCARG(uap, arg)) & FCNTLFLAGS;
  431                 error = (*fp->f_ops->fo_fcntl)(fp, F_SETFL, &tmp, p);
  432                 if (error)
  433                         break;
  434                 i = tmp ^ fp->f_flag;
  435                 if (i & FNONBLOCK) {
  436                         int fl = tmp & FNONBLOCK;
  437                         error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, &fl, p);
  438                         if (error)
  439                                 goto reset_fcntl;
  440                 }
  441                 if (i & FASYNC) {
  442                         int fl = tmp & FASYNC;
  443                         error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, &fl, p);
  444                         if (error) {
  445                                 if (i & FNONBLOCK) {
  446                                         tmp = fp->f_flag & FNONBLOCK;
  447                                         (void)(*fp->f_ops->fo_ioctl)(fp,
  448                                                 FIONBIO, &tmp, p);
  449                                 }
  450                                 goto reset_fcntl;
  451                         }
  452                 }
  453                 fp->f_flag = (fp->f_flag & ~FCNTLFLAGS) | tmp;
  454                 break;
  455             reset_fcntl:
  456                 (void)(*fp->f_ops->fo_fcntl)(fp, F_SETFL, &fp->f_flag, p);
  457                 break;
  458 
  459         case F_GETOWN:
  460                 error = (*fp->f_ops->fo_ioctl)(fp, FIOGETOWN, retval, p);
  461                 break;
  462 
  463         case F_SETOWN:
  464                 tmp = (int)(intptr_t) SCARG(uap, arg);
  465                 error = (*fp->f_ops->fo_ioctl)(fp, FIOSETOWN, &tmp, p);
  466                 break;
  467 
  468         case F_SETLKW:
  469                 flg |= F_WAIT;
  470                 /* Fall into F_SETLK */
  471 
  472         case F_SETLK:
  473                 if (fp->f_type != DTYPE_VNODE) {
  474                         error = EINVAL;
  475                         goto out;
  476                 }
  477                 vp = (struct vnode *)fp->f_data;
  478                 /* Copy in the lock structure */
  479                 error = copyin(SCARG(uap, arg), &fl, sizeof(fl));
  480                 if (error)
  481                         goto out;
  482                 if (fl.l_whence == SEEK_CUR)
  483                         fl.l_start += fp->f_offset;
  484                 switch (fl.l_type) {
  485                 case F_RDLCK:
  486                         if ((fp->f_flag & FREAD) == 0) {
  487                                 error = EBADF;
  488                                 goto out;
  489                         }
  490                         p->p_flag |= P_ADVLOCK;
  491                         error = VOP_ADVLOCK(vp, p, F_SETLK, &fl, flg);
  492                         goto out;
  493 
  494                 case F_WRLCK:
  495                         if ((fp->f_flag & FWRITE) == 0) {
  496                                 error = EBADF;
  497                                 goto out;
  498                         }
  499                         p->p_flag |= P_ADVLOCK;
  500                         error = VOP_ADVLOCK(vp, p, F_SETLK, &fl, flg);
  501                         goto out;
  502 
  503                 case F_UNLCK:
  504                         error = VOP_ADVLOCK(vp, p, F_UNLCK, &fl, F_POSIX);
  505                         goto out;
  506 
  507                 default:
  508                         error = EINVAL;
  509                         goto out;
  510                 }
  511 
  512         case F_GETLK:
  513                 if (fp->f_type != DTYPE_VNODE) {
  514                         error = EINVAL;
  515                         goto out;
  516                 }
  517                 vp = (struct vnode *)fp->f_data;
  518                 /* Copy in the lock structure */
  519                 error = copyin(SCARG(uap, arg), &fl, sizeof(fl));
  520                 if (error)
  521                         goto out;
  522                 if (fl.l_whence == SEEK_CUR)
  523                         fl.l_start += fp->f_offset;
  524                 if (fl.l_type != F_RDLCK &&
  525                     fl.l_type != F_WRLCK &&
  526                     fl.l_type != F_UNLCK) {
  527                         error = EINVAL;
  528                         goto out;
  529                 }
  530                 error = VOP_ADVLOCK(vp, p, F_GETLK, &fl, F_POSIX);
  531                 if (error)
  532                         goto out;
  533                 error = copyout(&fl, SCARG(uap, arg), sizeof(fl));
  534                 break;
  535 
  536         default:
  537                 error = EINVAL;
  538         }
  539 
  540  out:
  541         FILE_UNUSE(fp, p);
  542         return (error);
  543 }
  544 
  545 /*
  546  * Common code for dup, dup2, and fcntl(F_DUPFD).
  547  */
  548 int
  549 finishdup(struct proc *p, int old, int new, register_t *retval)
  550 {
  551         struct filedesc *fdp;
  552         struct file     *fp, *delfp;
  553 
  554         fdp = p->p_fd;
  555 
  556         /*
  557          * If there is a file in the new slot, remember it so we
  558          * can close it after we've finished the dup.  We need
  559          * to do it after the dup is finished, since closing
  560          * the file may block.
  561          *
  562          * Note: `old' is already used for us.
  563          * Note: Caller already marked `new' slot "used".
  564          */
  565         simple_lock(&fdp->fd_slock);
  566         delfp = fdp->fd_ofiles[new];
  567 
  568         fp = fdp->fd_ofiles[old];
  569         KDASSERT(fp != NULL);
  570         fdp->fd_ofiles[new] = fp;
  571         fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] &~ UF_EXCLOSE;
  572         simple_unlock(&fdp->fd_slock);
  573 
  574         *retval = new;
  575         simple_lock(&fp->f_slock);
  576         fp->f_count++;
  577         FILE_UNUSE_HAVELOCK(fp, p);
  578 
  579         if (delfp != NULL) {
  580                 simple_lock(&delfp->f_slock);
  581                 FILE_USE(delfp);
  582                 if (new < fdp->fd_knlistsize)
  583                         knote_fdclose(p, new);
  584                 (void) closef(delfp, p);
  585         }
  586         return (0);
  587 }
  588 
  589 void
  590 fdremove(struct filedesc *fdp, int fd)
  591 {
  592 
  593         simple_lock(&fdp->fd_slock);
  594         fdp->fd_ofiles[fd] = NULL;
  595         fd_unused(fdp, fd);
  596         simple_unlock(&fdp->fd_slock);
  597 }
  598 
  599 int
  600 fdrelease(struct proc *p, int fd)
  601 {
  602         struct filedesc *fdp;
  603         struct file     **fpp, *fp;
  604 
  605         fdp = p->p_fd;
  606         simple_lock(&fdp->fd_slock);
  607         if (fd < 0 || fd > fdp->fd_lastfile)
  608                 goto badf;
  609         fpp = &fdp->fd_ofiles[fd];
  610         fp = *fpp;
  611         if (fp == NULL)
  612                 goto badf;
  613 
  614         simple_lock(&fp->f_slock);
  615         if (!FILE_IS_USABLE(fp)) {
  616                 simple_unlock(&fp->f_slock);
  617                 goto badf;
  618         }
  619 
  620         FILE_USE(fp);
  621 
  622         *fpp = NULL;
  623         fdp->fd_ofileflags[fd] = 0;
  624         fd_unused(fdp, fd);
  625         simple_unlock(&fdp->fd_slock);
  626         if (fd < fdp->fd_knlistsize)
  627                 knote_fdclose(p, fd);
  628         return (closef(fp, p));
  629 
  630 badf:
  631         simple_unlock(&fdp->fd_slock);
  632         return (EBADF);
  633 }
  634 
  635 /*
  636  * Close a file descriptor.
  637  */
  638 /* ARGSUSED */
  639 int
  640 sys_close(struct lwp *l, void *v, register_t *retval)
  641 {
  642         struct sys_close_args /* {
  643                 syscallarg(int) fd;
  644         } */ *uap = v;
  645         int             fd;
  646         struct filedesc *fdp;
  647         struct proc *p;
  648 
  649         p = l->l_proc;
  650         fd = SCARG(uap, fd);
  651         fdp = p->p_fd;
  652 
  653 #if 0
  654         if (fd_getfile(fdp, fd) == NULL)
  655                 return (EBADF);
  656 #endif
  657 
  658         return (fdrelease(p, fd));
  659 }
  660 
  661 /*
  662  * Return status information about a file descriptor.
  663  */
  664 /* ARGSUSED */
  665 int
  666 sys___fstat13(struct lwp *l, void *v, register_t *retval)
  667 {
  668         struct sys___fstat13_args /* {
  669                 syscallarg(int)                 fd;
  670                 syscallarg(struct stat *)       sb;
  671         } */ *uap = v;
  672         int             fd;
  673         struct filedesc *fdp;
  674         struct file     *fp;
  675         struct proc     *p;
  676         struct stat     ub;
  677         int             error;
  678 
  679         p = l->l_proc;
  680         fd = SCARG(uap, fd);
  681         fdp = p->p_fd;
  682 
  683         if ((fp = fd_getfile(fdp, fd)) == NULL)
  684                 return (EBADF);
  685 
  686         FILE_USE(fp);
  687         error = (*fp->f_ops->fo_stat)(fp, &ub, p);
  688         FILE_UNUSE(fp, p);
  689 
  690         if (error == 0)
  691                 error = copyout(&ub, SCARG(uap, sb), sizeof(ub));
  692 
  693         return (error);
  694 }
  695 
  696 /*
  697  * Return pathconf information about a file descriptor.
  698  */
  699 /* ARGSUSED */
  700 int
  701 sys_fpathconf(struct lwp *l, void *v, register_t *retval)
  702 {
  703         struct sys_fpathconf_args /* {
  704                 syscallarg(int) fd;
  705                 syscallarg(int) name;
  706         } */ *uap = v;
  707         int             fd;
  708         struct filedesc *fdp;
  709         struct file     *fp;
  710         struct proc     *p;
  711         struct vnode    *vp;
  712         int             error;
  713 
  714         p = l->l_proc;
  715         fd = SCARG(uap, fd);
  716         fdp = p->p_fd;
  717         error = 0;
  718 
  719         if ((fp = fd_getfile(fdp, fd)) == NULL)
  720                 return (EBADF);
  721 
  722         FILE_USE(fp);
  723 
  724         switch (fp->f_type) {
  725 
  726         case DTYPE_SOCKET:
  727         case DTYPE_PIPE:
  728                 if (SCARG(uap, name) != _PC_PIPE_BUF)
  729                         error = EINVAL;
  730                 else
  731                         *retval = PIPE_BUF;
  732                 break;
  733 
  734         case DTYPE_VNODE:
  735                 vp = (struct vnode *)fp->f_data;
  736                 error = VOP_PATHCONF(vp, SCARG(uap, name), retval);
  737                 break;
  738 
  739         case DTYPE_KQUEUE:
  740                 error = EINVAL;
  741                 break;
  742 
  743         default:
  744                 error = EOPNOTSUPP;
  745                 break;
  746         }
  747 
  748         FILE_UNUSE(fp, p);
  749         return (error);
  750 }
  751 
  752 /*
  753  * Allocate a file descriptor for the process.
  754  */
  755 int     fdexpanded;             /* XXX: what else uses this? */
  756 
  757 int
  758 fdalloc(struct proc *p, int want, int *result)
  759 {
  760         struct filedesc *fdp;
  761         int i, lim, last, error;
  762         u_int off, new;
  763 
  764         fdp = p->p_fd;
  765         simple_lock(&fdp->fd_slock);
  766 
  767         /*
  768          * Search for a free descriptor starting at the higher
  769          * of want or fd_freefile.  If that fails, consider
  770          * expanding the ofile array.
  771          */
  772         lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfiles);
  773         last = min(fdp->fd_nfiles, lim);
  774  again:
  775         if ((i = want) < fdp->fd_freefile)
  776                 i = fdp->fd_freefile;
  777         off = i >> NDENTRYSHIFT;
  778         new = find_next_zero(fdp->fd_himap, off,
  779             (last + NDENTRIES - 1) >> NDENTRYSHIFT);
  780         if (new != -1) {
  781                 i = find_next_zero(&fdp->fd_lomap[new],
  782                     new > off ? 0 : i & NDENTRYMASK, NDENTRIES);
  783                 if (i == -1) {
  784                         /*
  785                          * free file descriptor in this block was
  786                          * below want, try again with higher want.
  787                          */
  788                         want = (new + 1) << NDENTRYSHIFT;
  789                         goto again;
  790                 }
  791                 i += (new << NDENTRYSHIFT);
  792                 if (i < last) {
  793                         if (fdp->fd_ofiles[i] == NULL) {
  794                                 fd_used(fdp, i);
  795                                 if (want <= fdp->fd_freefile)
  796                                         fdp->fd_freefile = i;
  797                                 *result = i;
  798                                 error = 0;
  799                                 goto out;
  800                         }
  801                 }
  802         }
  803 
  804         /* No space in current array.  Expand or let the caller do it. */
  805         error = (fdp->fd_nfiles >= lim) ? EMFILE : ENOSPC;
  806 
  807 out:
  808         simple_unlock(&fdp->fd_slock);
  809         return (error);
  810 }
  811 
  812 void
  813 fdexpand(struct proc *p)
  814 {
  815         struct filedesc *fdp;
  816         int             i, nfiles, oldnfiles;
  817         struct file     **newofile;
  818         char            *newofileflags;
  819         uint32_t        *newhimap = NULL, *newlomap = NULL;
  820 
  821         fdp = p->p_fd;
  822 
  823 restart:
  824         oldnfiles = fdp->fd_nfiles;
  825 
  826         if (oldnfiles < NDEXTENT)
  827                 nfiles = NDEXTENT;
  828         else
  829                 nfiles = 2 * oldnfiles;
  830 
  831         newofile = malloc(nfiles * OFILESIZE, M_FILEDESC, M_WAITOK);
  832         if (NDHISLOTS(nfiles) > NDHISLOTS(oldnfiles)) {
  833                 newhimap = malloc(NDHISLOTS(nfiles) * sizeof(uint32_t),
  834                     M_FILEDESC, M_WAITOK);
  835                 newlomap = malloc(NDLOSLOTS(nfiles) * sizeof(uint32_t),
  836                     M_FILEDESC, M_WAITOK);
  837         }
  838 
  839         simple_lock(&fdp->fd_slock);
  840         /* lock fdp */
  841         if (fdp->fd_nfiles != oldnfiles) {
  842                 /* fdp changed; retry */
  843                 simple_unlock(&fdp->fd_slock);
  844                 free(newofile, M_FILEDESC);
  845                 if (newhimap != NULL) free(newhimap, M_FILEDESC);
  846                 if (newlomap != NULL) free(newlomap, M_FILEDESC);
  847                 goto restart;
  848         }
  849 
  850         newofileflags = (char *) &newofile[nfiles];
  851         /*
  852          * Copy the existing ofile and ofileflags arrays
  853          * and zero the new portion of each array.
  854          */
  855         memcpy(newofile, fdp->fd_ofiles,
  856             (i = sizeof(struct file *) * fdp->fd_nfiles));
  857         memset((char *)newofile + i, 0,
  858             nfiles * sizeof(struct file *) - i);
  859         memcpy(newofileflags, fdp->fd_ofileflags,
  860             (i = sizeof(char) * fdp->fd_nfiles));
  861         memset(newofileflags + i, 0, nfiles * sizeof(char) - i);
  862         if (oldnfiles > NDFILE)
  863                 free(fdp->fd_ofiles, M_FILEDESC);
  864 
  865         if (NDHISLOTS(nfiles) > NDHISLOTS(oldnfiles)) {
  866                 memcpy(newhimap, fdp->fd_himap,
  867                     (i = NDHISLOTS(oldnfiles) * sizeof(uint32_t)));
  868                 memset((char *)newhimap + i, 0,
  869                     NDHISLOTS(nfiles) * sizeof(uint32_t) - i);
  870 
  871                 memcpy(newlomap, fdp->fd_lomap,
  872                     (i = NDLOSLOTS(oldnfiles) * sizeof(uint32_t)));
  873                 memset((char *)newlomap + i, 0,
  874                     NDLOSLOTS(nfiles) * sizeof(uint32_t) - i);
  875 
  876                 if (NDHISLOTS(oldnfiles) > NDHISLOTS(NDFILE)) {
  877                         free(fdp->fd_himap, M_FILEDESC);
  878                         free(fdp->fd_lomap, M_FILEDESC);
  879                 }
  880                 fdp->fd_himap = newhimap;
  881                 fdp->fd_lomap = newlomap;
  882         }
  883 
  884         fdp->fd_ofiles = newofile;
  885         fdp->fd_ofileflags = newofileflags;
  886         fdp->fd_nfiles = nfiles;
  887 
  888         simple_unlock(&fdp->fd_slock);
  889 
  890         fdexpanded++;
  891 }
  892 
  893 /*
  894  * Check to see whether n user file descriptors
  895  * are available to the process p.
  896  */
  897 int
  898 fdavail(struct proc *p, int n)
  899 {
  900         struct filedesc *fdp;
  901         struct file     **fpp;
  902         int             i, lim;
  903 
  904         fdp = p->p_fd;
  905         lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfiles);
  906         if ((i = lim - fdp->fd_nfiles) > 0 && (n -= i) <= 0)
  907                 return (1);
  908         fpp = &fdp->fd_ofiles[fdp->fd_freefile];
  909         for (i = min(lim,fdp->fd_nfiles) - fdp->fd_freefile; --i >= 0; fpp++)
  910                 if (*fpp == NULL && --n <= 0)
  911                         return (1);
  912         return (0);
  913 }
  914 
  915 /*
  916  * Create a new open file structure and allocate
  917  * a file descriptor for the process that refers to it.
  918  */
  919 int
  920 falloc(struct proc *p, struct file **resultfp, int *resultfd)
  921 {
  922         struct file     *fp, *fq;
  923         int             error, i;
  924 
  925  restart:
  926         if ((error = fdalloc(p, 0, &i)) != 0) {
  927                 if (error == ENOSPC) {
  928                         fdexpand(p);
  929                         goto restart;
  930                 }
  931                 return (error);
  932         }
  933 
  934         fp = pool_get(&file_pool, PR_WAITOK);
  935         simple_lock(&filelist_slock);
  936         if (nfiles >= maxfiles) {
  937                 tablefull("file", "increase kern.maxfiles or MAXFILES");
  938                 simple_unlock(&filelist_slock);
  939                 fd_unused(p->p_fd, i);
  940                 pool_put(&file_pool, fp);
  941                 return (ENFILE);
  942         }
  943         /*
  944          * Allocate a new file descriptor.
  945          * If the process has file descriptor zero open, add to the list
  946          * of open files at that point, otherwise put it at the front of
  947          * the list of open files.
  948          */
  949         nfiles++;
  950         memset(fp, 0, sizeof(struct file));
  951         fp->f_iflags = FIF_LARVAL;
  952         if ((fq = p->p_fd->fd_ofiles[0]) != NULL) {
  953                 LIST_INSERT_AFTER(fq, fp, f_list);
  954         } else {
  955                 LIST_INSERT_HEAD(&filehead, fp, f_list);
  956         }
  957         simple_unlock(&filelist_slock);
  958         KDASSERT(p->p_fd->fd_ofiles[i] == NULL);
  959         p->p_fd->fd_ofiles[i] = fp;
  960         simple_lock_init(&fp->f_slock);
  961         fp->f_count = 1;
  962         fp->f_cred = p->p_ucred;
  963         crhold(fp->f_cred);
  964         if (resultfp) {
  965                 fp->f_usecount = 1;
  966                 *resultfp = fp;
  967         }
  968         if (resultfd)
  969                 *resultfd = i;
  970         return (0);
  971 }
  972 
  973 /*
  974  * Free a file descriptor.
  975  */
  976 void
  977 ffree(struct file *fp)
  978 {
  979 
  980 #ifdef DIAGNOSTIC
  981         if (fp->f_usecount)
  982                 panic("ffree");
  983 #endif
  984 
  985         simple_lock(&filelist_slock);
  986         LIST_REMOVE(fp, f_list);
  987         crfree(fp->f_cred);
  988 #ifdef DIAGNOSTIC
  989         fp->f_count = 0; /* What's the point? */
  990 #endif
  991         nfiles--;
  992         simple_unlock(&filelist_slock);
  993         pool_put(&file_pool, fp);
  994 }
  995 
  996 /*
  997  * Create an initial cwdinfo structure, using the same current and root
  998  * directories as p.
  999  */
 1000 struct cwdinfo *
 1001 cwdinit(struct proc *p)
 1002 {
 1003         struct cwdinfo *cwdi;
 1004 
 1005         cwdi = pool_get(&cwdi_pool, PR_WAITOK);
 1006 
 1007         simple_lock_init(&cwdi->cwdi_slock);
 1008         cwdi->cwdi_cdir = p->p_cwdi->cwdi_cdir;
 1009         if (cwdi->cwdi_cdir)
 1010                 VREF(cwdi->cwdi_cdir);
 1011         cwdi->cwdi_rdir = p->p_cwdi->cwdi_rdir;
 1012         if (cwdi->cwdi_rdir)
 1013                 VREF(cwdi->cwdi_rdir);
 1014         cwdi->cwdi_cmask =  p->p_cwdi->cwdi_cmask;
 1015         cwdi->cwdi_refcnt = 1;
 1016 
 1017         return (cwdi);
 1018 }
 1019 
 1020 /*
 1021  * Make p2 share p1's cwdinfo.
 1022  */
 1023 void
 1024 cwdshare(struct proc *p1, struct proc *p2)
 1025 {
 1026         struct cwdinfo *cwdi = p1->p_cwdi;
 1027 
 1028         simple_lock(&cwdi->cwdi_slock);
 1029         cwdi->cwdi_refcnt++;
 1030         simple_unlock(&cwdi->cwdi_slock);
 1031         p2->p_cwdi = cwdi;
 1032 }
 1033 
 1034 /*
 1035  * Make this process not share its cwdinfo structure, maintaining
 1036  * all cwdinfo state.
 1037  */
 1038 void
 1039 cwdunshare(struct proc *p)
 1040 {
 1041         struct cwdinfo *oldcwdi, *newcwdi;
 1042 
 1043         if (p->p_cwdi->cwdi_refcnt == 1)
 1044                 return;
 1045 
 1046         newcwdi = cwdinit(p);
 1047         oldcwdi = p->p_cwdi;
 1048         p->p_cwdi = newcwdi;
 1049         cwdfree(oldcwdi);
 1050 }
 1051 
 1052 /*
 1053  * Release a cwdinfo structure.
 1054  */
 1055 void
 1056 cwdfree(struct cwdinfo *cwdi)
 1057 {
 1058         int n;
 1059 
 1060         simple_lock(&cwdi->cwdi_slock);
 1061         n = --cwdi->cwdi_refcnt;
 1062         simple_unlock(&cwdi->cwdi_slock);
 1063         if (n > 0)
 1064                 return;
 1065 
 1066         vrele(cwdi->cwdi_cdir);
 1067         if (cwdi->cwdi_rdir)
 1068                 vrele(cwdi->cwdi_rdir);
 1069         pool_put(&cwdi_pool, cwdi);
 1070 }
 1071 
 1072 /*
 1073  * Create an initial filedesc structure, using the same current and root
 1074  * directories as p.
 1075  */
 1076 struct filedesc *
 1077 fdinit(struct proc *p)
 1078 {
 1079         struct filedesc0 *newfdp;
 1080 
 1081         newfdp = pool_get(&filedesc0_pool, PR_WAITOK);
 1082         memset(newfdp, 0, sizeof(struct filedesc0));
 1083 
 1084         fdinit1(newfdp);
 1085 
 1086         return (&newfdp->fd_fd);
 1087 }
 1088 
 1089 /*
 1090  * Initialize a file descriptor table.
 1091  */
 1092 void
 1093 fdinit1(struct filedesc0 *newfdp)
 1094 {
 1095 
 1096         newfdp->fd_fd.fd_refcnt = 1;
 1097         newfdp->fd_fd.fd_ofiles = newfdp->fd_dfiles;
 1098         newfdp->fd_fd.fd_ofileflags = newfdp->fd_dfileflags;
 1099         newfdp->fd_fd.fd_nfiles = NDFILE;
 1100         newfdp->fd_fd.fd_knlistsize = -1;
 1101         newfdp->fd_fd.fd_himap = newfdp->fd_dhimap;
 1102         newfdp->fd_fd.fd_lomap = newfdp->fd_dlomap;
 1103         newfdp->fd_fd.fd_lastfile = -1;
 1104         simple_lock_init(&newfdp->fd_fd.fd_slock);
 1105 }
 1106 
 1107 /*
 1108  * Make p2 share p1's filedesc structure.
 1109  */
 1110 void
 1111 fdshare(struct proc *p1, struct proc *p2)
 1112 {
 1113         struct filedesc *fdp = p1->p_fd;
 1114 
 1115         simple_lock(&fdp->fd_slock);
 1116         p2->p_fd = fdp;
 1117         fdp->fd_refcnt++;
 1118         simple_unlock(&fdp->fd_slock);
 1119 }
 1120 
 1121 /*
 1122  * Make this process not share its filedesc structure, maintaining
 1123  * all file descriptor state.
 1124  */
 1125 void
 1126 fdunshare(struct proc *p)
 1127 {
 1128         struct filedesc *newfd;
 1129 
 1130         if (p->p_fd->fd_refcnt == 1)
 1131                 return;
 1132 
 1133         newfd = fdcopy(p);
 1134         fdfree(p);
 1135         p->p_fd = newfd;
 1136 }
 1137 
 1138 /*
 1139  * Clear a process's fd table.
 1140  */
 1141 void
 1142 fdclear(struct proc *p)
 1143 {
 1144         struct filedesc *newfd;
 1145 
 1146         newfd = fdinit(p);
 1147         fdfree(p);
 1148         p->p_fd = newfd;
 1149 }
 1150 
 1151 /*
 1152  * Copy a filedesc structure.
 1153  */
 1154 struct filedesc *
 1155 fdcopy(struct proc *p)
 1156 {
 1157         struct filedesc *newfdp, *fdp;
 1158         struct file     **fpp, **nfpp;
 1159         int             i, nfiles, lastfile;
 1160 
 1161         fdp = p->p_fd;
 1162         newfdp = pool_get(&filedesc0_pool, PR_WAITOK);
 1163         newfdp->fd_refcnt = 1;
 1164         simple_lock_init(&newfdp->fd_slock);
 1165 
 1166 restart:
 1167         nfiles = fdp->fd_nfiles;
 1168         lastfile = fdp->fd_lastfile;
 1169 
 1170         /*
 1171          * If the number of open files fits in the internal arrays
 1172          * of the open file structure, use them, otherwise allocate
 1173          * additional memory for the number of descriptors currently
 1174          * in use.
 1175          */
 1176         if (lastfile < NDFILE) {
 1177                 i = NDFILE;
 1178         } else {
 1179                 /*
 1180                  * Compute the smallest multiple of NDEXTENT needed
 1181                  * for the file descriptors currently in use,
 1182                  * allowing the table to shrink.
 1183                  */
 1184                 i = nfiles;
 1185                 while (i >= 2 * NDEXTENT && i > lastfile * 2)
 1186                         i /= 2;
 1187                 newfdp->fd_ofiles = malloc(i * OFILESIZE, M_FILEDESC, M_WAITOK);
 1188         }
 1189         if (NDHISLOTS(i) > NDHISLOTS(NDFILE)) {
 1190                 newfdp->fd_himap = malloc(NDHISLOTS(i) * sizeof(uint32_t),
 1191                     M_FILEDESC, M_WAITOK);
 1192                 newfdp->fd_lomap = malloc(NDLOSLOTS(i) * sizeof(uint32_t),
 1193                     M_FILEDESC, M_WAITOK);
 1194         }
 1195 
 1196         simple_lock(&fdp->fd_slock);
 1197         if (nfiles != fdp->fd_nfiles || lastfile != fdp->fd_lastfile) {
 1198                 simple_unlock(&fdp->fd_slock);
 1199                 if (i > NDFILE)
 1200                         free(newfdp->fd_ofiles, M_FILEDESC);
 1201                 if (NDHISLOTS(i) > NDHISLOTS(NDFILE)) {
 1202                         free(newfdp->fd_himap, M_FILEDESC);
 1203                         free(newfdp->fd_lomap, M_FILEDESC);
 1204                 }
 1205                 goto restart;
 1206         }
 1207 
 1208         if (lastfile < NDFILE) {
 1209                 newfdp->fd_ofiles = ((struct filedesc0 *) newfdp)->fd_dfiles;
 1210                 newfdp->fd_ofileflags =
 1211                     ((struct filedesc0 *) newfdp)->fd_dfileflags;
 1212         } else {
 1213                 newfdp->fd_ofileflags = (char *) &newfdp->fd_ofiles[i];
 1214         }
 1215         if (NDHISLOTS(i) <= NDHISLOTS(NDFILE)) {
 1216                 newfdp->fd_himap =
 1217                     ((struct filedesc0 *) newfdp)->fd_dhimap;
 1218                 newfdp->fd_lomap =
 1219                     ((struct filedesc0 *) newfdp)->fd_dlomap;
 1220         }
 1221 
 1222         newfdp->fd_nfiles = i;
 1223         newfdp->fd_lastfile = lastfile;
 1224         newfdp->fd_freefile = fdp->fd_freefile;
 1225 
 1226         /* Clear the entries that will not be copied over.
 1227          * Avoid calling memset with 0 size (i.e. when
 1228          * lastfile == i-1 */
 1229         if (lastfile < (i-1))
 1230                 memset(newfdp->fd_ofiles + lastfile + 1, 0,
 1231                     (i - lastfile - 1) * sizeof(struct file **));
 1232         memcpy(newfdp->fd_ofileflags, fdp->fd_ofileflags, i * sizeof(char));
 1233         if (i < NDENTRIES * NDENTRIES)
 1234                 i = NDENTRIES * NDENTRIES; /* size of inlined bitmaps */
 1235         memcpy(newfdp->fd_himap, fdp->fd_himap, NDHISLOTS(i)*sizeof(uint32_t));
 1236         memcpy(newfdp->fd_lomap, fdp->fd_lomap, NDLOSLOTS(i)*sizeof(uint32_t));
 1237 
 1238         fpp = fdp->fd_ofiles;
 1239         nfpp = newfdp->fd_ofiles;
 1240         for (i = 0; i <= lastfile; i++, fpp++, nfpp++) {
 1241                 if ((*nfpp = *fpp) == NULL)
 1242                         continue;
 1243 
 1244                 if ((*fpp)->f_type == DTYPE_KQUEUE)
 1245                         /* kq descriptors cannot be copied. */
 1246                         fdremove(newfdp, i);
 1247                 else {
 1248                         simple_lock(&(*fpp)->f_slock);
 1249                         (*fpp)->f_count++;
 1250                         simple_unlock(&(*fpp)->f_slock);
 1251                 }
 1252         }
 1253 
 1254         simple_unlock(&fdp->fd_slock);
 1255 
 1256         newfdp->fd_knlist = NULL;
 1257         newfdp->fd_knlistsize = -1;
 1258         newfdp->fd_knhash = NULL;
 1259         newfdp->fd_knhashmask = 0;
 1260 
 1261         return (newfdp);
 1262 }
 1263 
 1264 /*
 1265  * Release a filedesc structure.
 1266  */
 1267 void
 1268 fdfree(struct proc *p)
 1269 {
 1270         struct filedesc *fdp;
 1271         struct file     **fpp, *fp;
 1272         int             i;
 1273 
 1274         fdp = p->p_fd;
 1275         simple_lock(&fdp->fd_slock);
 1276         i = --fdp->fd_refcnt;
 1277         simple_unlock(&fdp->fd_slock);
 1278         if (i > 0)
 1279                 return;
 1280 
 1281         fpp = fdp->fd_ofiles;
 1282         for (i = fdp->fd_lastfile; i >= 0; i--, fpp++) {
 1283                 fp = *fpp;
 1284                 if (fp != NULL) {
 1285                         *fpp = NULL;
 1286                         simple_lock(&fp->f_slock);
 1287                         FILE_USE(fp);
 1288                         if ((fdp->fd_lastfile - i) < fdp->fd_knlistsize)
 1289                                 knote_fdclose(p, fdp->fd_lastfile - i);
 1290                         (void) closef(fp, p);
 1291                 }
 1292         }
 1293         p->p_fd = NULL;
 1294         if (fdp->fd_nfiles > NDFILE)
 1295                 free(fdp->fd_ofiles, M_FILEDESC);
 1296         if (NDHISLOTS(fdp->fd_nfiles) > NDHISLOTS(NDFILE)) {
 1297                 free(fdp->fd_himap, M_FILEDESC);
 1298                 free(fdp->fd_lomap, M_FILEDESC);
 1299         }
 1300         if (fdp->fd_knlist)
 1301                 free(fdp->fd_knlist, M_KEVENT);
 1302         if (fdp->fd_knhash)
 1303                 hashdone(fdp->fd_knhash, M_KEVENT);
 1304         pool_put(&filedesc0_pool, fdp);
 1305 }
 1306 
 1307 /*
 1308  * Internal form of close.
 1309  * Decrement reference count on file structure.
 1310  * Note: p may be NULL when closing a file
 1311  * that was being passed in a message.
 1312  *
 1313  * Note: we expect the caller is holding a usecount, and expects us
 1314  * to drop it (the caller thinks the file is going away forever).
 1315  */
 1316 int
 1317 closef(struct file *fp, struct proc *p)
 1318 {
 1319         struct vnode    *vp;
 1320         struct flock    lf;
 1321         int             error;
 1322 
 1323         if (fp == NULL)
 1324                 return (0);
 1325 
 1326         /*
 1327          * POSIX record locking dictates that any close releases ALL
 1328          * locks owned by this process.  This is handled by setting
 1329          * a flag in the unlock to free ONLY locks obeying POSIX
 1330          * semantics, and not to free BSD-style file locks.
 1331          * If the descriptor was in a message, POSIX-style locks
 1332          * aren't passed with the descriptor.
 1333          */
 1334         if (p && (p->p_flag & P_ADVLOCK) && fp->f_type == DTYPE_VNODE) {
 1335                 lf.l_whence = SEEK_SET;
 1336                 lf.l_start = 0;
 1337                 lf.l_len = 0;
 1338                 lf.l_type = F_UNLCK;
 1339                 vp = (struct vnode *)fp->f_data;
 1340                 (void) VOP_ADVLOCK(vp, p, F_UNLCK, &lf, F_POSIX);
 1341         }
 1342 
 1343         /*
 1344          * If WANTCLOSE is set, then the reference count on the file
 1345          * is 0, but there were multiple users of the file.  This can
 1346          * happen if a filedesc structure is shared by multiple
 1347          * processes.
 1348          */
 1349         simple_lock(&fp->f_slock);
 1350         if (fp->f_iflags & FIF_WANTCLOSE) {
 1351                 /*
 1352                  * Another user of the file is already closing, and is
 1353                  * simply waiting for other users of the file to drain.
 1354                  * Release our usecount, and wake up the closer if it
 1355                  * is the only remaining use.
 1356                  */
 1357 #ifdef DIAGNOSTIC
 1358                 if (fp->f_count != 0)
 1359                         panic("closef: wantclose and count != 0");
 1360                 if (fp->f_usecount < 2)
 1361                         panic("closef: wantclose and usecount < 2");
 1362 #endif
 1363                 if (--fp->f_usecount == 1)
 1364                         wakeup(&fp->f_usecount);
 1365                 simple_unlock(&fp->f_slock);
 1366                 return (0);
 1367         } else {
 1368                 /*
 1369                  * Decrement the reference count.  If we were not the
 1370                  * last reference, then release our use and just
 1371                  * return.
 1372                  */
 1373                 if (--fp->f_count > 0) {
 1374 #ifdef DIAGNOSTIC
 1375                         if (fp->f_usecount < 1)
 1376                                 panic("closef: no wantclose and usecount < 1");
 1377 #endif
 1378                         fp->f_usecount--;
 1379                         simple_unlock(&fp->f_slock);
 1380                         return (0);
 1381                 }
 1382         }
 1383 
 1384         /*
 1385          * The reference count is now 0.  However, there may be
 1386          * multiple potential users of this file.  This can happen
 1387          * if multiple processes shared a single filedesc structure.
 1388          *
 1389          * Notify these potential users that the file is closing.
 1390          * This will prevent them from adding additional uses to
 1391          * the file.
 1392          */
 1393         fp->f_iflags |= FIF_WANTCLOSE;
 1394 
 1395         /*
 1396          * We expect the caller to add a use to the file.  So, if we
 1397          * are the last user, usecount will be 1.  If it is not, we
 1398          * must wait for the usecount to drain.  When it drains back
 1399          * to 1, we will be awakened so that we may proceed with the
 1400          * close.
 1401          */
 1402 #ifdef DIAGNOSTIC
 1403         if (fp->f_usecount < 1)
 1404                 panic("closef: usecount < 1");
 1405 #endif
 1406         while (fp->f_usecount > 1)
 1407                 (void) ltsleep(&fp->f_usecount, PRIBIO, "closef", 0,
 1408                                 &fp->f_slock);
 1409 #ifdef DIAGNOSTIC
 1410         if (fp->f_usecount != 1)
 1411                 panic("closef: usecount != 1");
 1412 #endif
 1413 
 1414         simple_unlock(&fp->f_slock);
 1415         if ((fp->f_flag & FHASLOCK) && fp->f_type == DTYPE_VNODE) {
 1416                 lf.l_whence = SEEK_SET;
 1417                 lf.l_start = 0;
 1418                 lf.l_len = 0;
 1419                 lf.l_type = F_UNLCK;
 1420                 vp = (struct vnode *)fp->f_data;
 1421                 (void) VOP_ADVLOCK(vp, fp, F_UNLCK, &lf, F_FLOCK);
 1422         }
 1423         if (fp->f_ops)
 1424                 error = (*fp->f_ops->fo_close)(fp, p);
 1425         else
 1426                 error = 0;
 1427 
 1428         /* Nothing references the file now, drop the final use (us). */
 1429         fp->f_usecount--;
 1430 
 1431         ffree(fp);
 1432         return (error);
 1433 }
 1434 
 1435 /*
 1436  * Apply an advisory lock on a file descriptor.
 1437  *
 1438  * Just attempt to get a record lock of the requested type on
 1439  * the entire file (l_whence = SEEK_SET, l_start = 0, l_len = 0).
 1440  */
 1441 /* ARGSUSED */
 1442 int
 1443 sys_flock(struct lwp *l, void *v, register_t *retval)
 1444 {
 1445         struct sys_flock_args /* {
 1446                 syscallarg(int) fd;
 1447                 syscallarg(int) how;
 1448         } */ *uap = v;
 1449         int             fd, how, error;
 1450         struct proc     *p;
 1451         struct filedesc *fdp;
 1452         struct file     *fp;
 1453         struct vnode    *vp;
 1454         struct flock    lf;
 1455 
 1456         p = l->l_proc;
 1457         fd = SCARG(uap, fd);
 1458         how = SCARG(uap, how);
 1459         fdp = p->p_fd;
 1460         error = 0;
 1461 
 1462         if ((fp = fd_getfile(fdp, fd)) == NULL)
 1463                 return (EBADF);
 1464 
 1465         FILE_USE(fp);
 1466 
 1467         if (fp->f_type != DTYPE_VNODE) {
 1468                 error = EOPNOTSUPP;
 1469                 goto out;
 1470         }
 1471 
 1472         vp = (struct vnode *)fp->f_data;
 1473         lf.l_whence = SEEK_SET;
 1474         lf.l_start = 0;
 1475         lf.l_len = 0;
 1476         if (how & LOCK_UN) {
 1477                 lf.l_type = F_UNLCK;
 1478                 fp->f_flag &= ~FHASLOCK;
 1479                 error = VOP_ADVLOCK(vp, fp, F_UNLCK, &lf, F_FLOCK);
 1480                 goto out;
 1481         }
 1482         if (how & LOCK_EX)
 1483                 lf.l_type = F_WRLCK;
 1484         else if (how & LOCK_SH)
 1485                 lf.l_type = F_RDLCK;
 1486         else {
 1487                 error = EINVAL;
 1488                 goto out;
 1489         }
 1490         fp->f_flag |= FHASLOCK;
 1491         if (how & LOCK_NB)
 1492                 error = VOP_ADVLOCK(vp, fp, F_SETLK, &lf, F_FLOCK);
 1493         else
 1494                 error = VOP_ADVLOCK(vp, fp, F_SETLK, &lf,
 1495                     F_FLOCK|F_WAIT);
 1496  out:
 1497         FILE_UNUSE(fp, p);
 1498         return (error);
 1499 }
 1500 
 1501 /*
 1502  * File Descriptor pseudo-device driver (/dev/fd/).
 1503  *
 1504  * Opening minor device N dup()s the file (if any) connected to file
 1505  * descriptor N belonging to the calling process.  Note that this driver
 1506  * consists of only the ``open()'' routine, because all subsequent
 1507  * references to this file will be direct to the other driver.
 1508  */
 1509 /* ARGSUSED */
 1510 int
 1511 filedescopen(dev_t dev, int mode, int type, struct proc *p)
 1512 {
 1513 
 1514         /*
 1515          * XXX Kludge: set dupfd to contain the value of the
 1516          * the file descriptor being sought for duplication. The error
 1517          * return ensures that the vnode for this device will be released
 1518          * by vn_open. Open will detect this special error and take the
 1519          * actions in dupfdopen below. Other callers of vn_open or VOP_OPEN
 1520          * will simply report the error.
 1521          */
 1522         curlwp->l_dupfd = minor(dev);   /* XXX */
 1523         return EDUPFD;
 1524 }
 1525 
 1526 /*
 1527  * Duplicate the specified descriptor to a free descriptor.
 1528  *
 1529  * 'indx' has been fdalloc'ed (and will be fdremove'ed on error) by the caller.
 1530  */
 1531 int
 1532 dupfdopen(struct proc *p, int indx, int dfd, int mode, int error)
 1533 {
 1534         struct filedesc *fdp;
 1535         struct file     *wfp;
 1536 
 1537         fdp = p->p_fd;
 1538 
 1539         /* should be cleared by the caller */
 1540         KASSERT(fdp->fd_ofiles[indx] == NULL);
 1541 
 1542         /*
 1543          * If the to-be-dup'd fd number is greater than the allowed number
 1544          * of file descriptors, or the fd to be dup'd has already been
 1545          * closed, reject.
 1546          */
 1547 
 1548         /*
 1549          * Note, in the case of indx == dfd, fd_getfile below returns NULL.
 1550          */
 1551         if ((wfp = fd_getfile(fdp, dfd)) == NULL)
 1552                 return (EBADF);
 1553 
 1554         FILE_USE(wfp);
 1555 
 1556         /*
 1557          * There are two cases of interest here.
 1558          *
 1559          * For EDUPFD simply dup (dfd) to file descriptor
 1560          * (indx) and return.
 1561          *
 1562          * For EMOVEFD steal away the file structure from (dfd) and
 1563          * store it in (indx).  (dfd) is effectively closed by
 1564          * this operation.
 1565          *
 1566          * Any other error code is just returned.
 1567          */
 1568         switch (error) {
 1569         case EDUPFD:
 1570                 /*
 1571                  * Check that the mode the file is being opened for is a
 1572                  * subset of the mode of the existing descriptor.
 1573                  */
 1574                 if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag) {
 1575                         FILE_UNUSE(wfp, p);
 1576                         return (EACCES);
 1577                 }
 1578                 simple_lock(&fdp->fd_slock);
 1579                 fdp->fd_ofiles[indx] = wfp;
 1580                 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];
 1581                 simple_unlock(&fdp->fd_slock);
 1582                 simple_lock(&wfp->f_slock);
 1583                 wfp->f_count++;
 1584                 /* 'indx' has been fd_used'ed by caller */
 1585                 FILE_UNUSE_HAVELOCK(wfp, p);
 1586                 return (0);
 1587 
 1588         case EMOVEFD:
 1589                 /*
 1590                  * Steal away the file pointer from dfd, and stuff it into indx.
 1591                  */
 1592                 simple_lock(&fdp->fd_slock);
 1593                 fdp->fd_ofiles[indx] = fdp->fd_ofiles[dfd];
 1594                 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];
 1595                 fdp->fd_ofiles[dfd] = NULL;
 1596                 fdp->fd_ofileflags[dfd] = 0;
 1597                 /*
 1598                  * Complete the clean up of the filedesc structure by
 1599                  * recomputing the various hints.
 1600                  */
 1601                 /* 'indx' has been fd_used'ed by caller */
 1602                 fd_unused(fdp, dfd);
 1603                 simple_unlock(&fdp->fd_slock);
 1604                 FILE_UNUSE(wfp, p);
 1605                 return (0);
 1606 
 1607         default:
 1608                 FILE_UNUSE(wfp, p);
 1609                 return (error);
 1610         }
 1611         /* NOTREACHED */
 1612 }
 1613 
 1614 /*
 1615  * fcntl call which is being passed to the file's fs.
 1616  */
 1617 int
 1618 fcntl_forfs(int fd, struct proc *p, int cmd, void *arg)
 1619 {
 1620         struct file     *fp;
 1621         struct filedesc *fdp;
 1622         int             error;
 1623         u_int           size;
 1624         void            *data, *memp;
 1625 #define STK_PARAMS      128
 1626         char            stkbuf[STK_PARAMS];
 1627 
 1628         /* fd's value was validated in sys_fcntl before calling this routine */
 1629         fdp = p->p_fd;
 1630         fp = fdp->fd_ofiles[fd];
 1631 
 1632         if ((fp->f_flag & (FREAD | FWRITE)) == 0)
 1633                 return (EBADF);
 1634 
 1635         /*
 1636          * Interpret high order word to find amount of data to be
 1637          * copied to/from the user's address space.
 1638          */
 1639         size = (size_t)F_PARAM_LEN(cmd);
 1640         if (size > F_PARAM_MAX)
 1641                 return (EINVAL);
 1642         memp = NULL;
 1643         if (size > sizeof(stkbuf)) {
 1644                 memp = malloc((u_long)size, M_IOCTLOPS, M_WAITOK);
 1645                 data = memp;
 1646         } else
 1647                 data = stkbuf;
 1648         if (cmd & F_FSIN) {
 1649                 if (size) {
 1650                         error = copyin(arg, data, size);
 1651                         if (error) {
 1652                                 if (memp)
 1653                                         free(memp, M_IOCTLOPS);
 1654                                 return (error);
 1655                         }
 1656                 } else
 1657                         *(void **)data = arg;
 1658         } else if ((cmd & F_FSOUT) && size)
 1659                 /*
 1660                  * Zero the buffer so the user always
 1661                  * gets back something deterministic.
 1662                  */
 1663                 memset(data, 0, size);
 1664         else if (cmd & F_FSVOID)
 1665                 *(void **)data = arg;
 1666 
 1667 
 1668         error = (*fp->f_ops->fo_fcntl)(fp, cmd, data, p);
 1669 
 1670         /*
 1671          * Copy any data to user, size was
 1672          * already set and checked above.
 1673          */
 1674         if (error == 0 && (cmd & F_FSOUT) && size)
 1675                 error = copyout(data, arg, size);
 1676         if (memp)
 1677                 free(memp, M_IOCTLOPS);
 1678         return (error);
 1679 }
 1680 
 1681 /*
 1682  * Close any files on exec?
 1683  */
 1684 void
 1685 fdcloseexec(struct proc *p)
 1686 {
 1687         struct filedesc *fdp;
 1688         int             fd;
 1689 
 1690         fdunshare(p);
 1691         cwdunshare(p);
 1692 
 1693         fdp = p->p_fd;
 1694         for (fd = 0; fd <= fdp->fd_lastfile; fd++)
 1695                 if (fdp->fd_ofileflags[fd] & UF_EXCLOSE)
 1696                         (void) fdrelease(p, fd);
 1697 }
 1698 
 1699 /*
 1700  * It is unsafe for set[ug]id processes to be started with file
 1701  * descriptors 0..2 closed, as these descriptors are given implicit
 1702  * significance in the Standard C library.  fdcheckstd() will create a
 1703  * descriptor referencing /dev/null for each of stdin, stdout, and
 1704  * stderr that is not already open.
 1705  */
 1706 #define CHECK_UPTO 3
 1707 int
 1708 fdcheckstd(p)
 1709         struct proc *p;
 1710 {
 1711         struct nameidata nd;
 1712         struct filedesc *fdp;
 1713         struct file *fp;
 1714         struct file *devnullfp = NULL;  /* Quell compiler warning */
 1715         struct proc *pp;
 1716         register_t retval;
 1717         int fd, i, error, flags = FREAD|FWRITE, devnull = -1;
 1718         char closed[CHECK_UPTO * 3 + 1], which[3 + 1];
 1719 
 1720         closed[0] = '\0';
 1721         if ((fdp = p->p_fd) == NULL)
 1722                 return (0);
 1723         for (i = 0; i < CHECK_UPTO; i++) {
 1724                 if (fdp->fd_ofiles[i] != NULL)
 1725                         continue;
 1726                 snprintf(which, sizeof(which), ",%d", i);
 1727                 strlcat(closed, which, sizeof(closed));
 1728                 if (devnull < 0) {
 1729                         if ((error = falloc(p, &fp, &fd)) != 0)
 1730                                 return (error);
 1731                         NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/dev/null",
 1732                             p);
 1733                         if ((error = vn_open(&nd, flags, 0)) != 0) {
 1734                                 FILE_UNUSE(fp, p);
 1735                                 ffree(fp);
 1736                                 fdremove(p->p_fd, fd);
 1737                                 return (error);
 1738                         }
 1739                         fp->f_data = nd.ni_vp;
 1740                         fp->f_flag = flags;
 1741                         fp->f_ops = &vnops;
 1742                         fp->f_type = DTYPE_VNODE;
 1743                         VOP_UNLOCK(nd.ni_vp, 0);
 1744                         devnull = fd;
 1745                         devnullfp = fp;
 1746                         FILE_SET_MATURE(fp);
 1747                 } else {
 1748 restart:
 1749                         if ((error = fdalloc(p, 0, &fd)) != 0) {
 1750                                 if (error == ENOSPC) {
 1751                                         fdexpand(p);
 1752                                         goto restart;
 1753                                 }
 1754                                 return (error);
 1755                         }
 1756 
 1757                         simple_lock(&devnullfp->f_slock);
 1758                         FILE_USE(devnullfp);
 1759                         /* finishdup() will unuse the descriptors for us */
 1760                         if ((error = finishdup(p, devnull, fd, &retval)) != 0)
 1761                                 return (error);
 1762                 }
 1763         }
 1764         if (devnullfp)
 1765                 FILE_UNUSE(devnullfp, p);
 1766         if (closed[0] != '\0') {
 1767                 pp = p->p_pptr;
 1768                 log(LOG_WARNING, "set{u,g}id pid %d (%s) "
 1769                     "was invoked by uid %d ppid %d (%s) "
 1770                     "with fd %s closed\n",
 1771                     p->p_pid, p->p_comm, pp->p_ucred->cr_uid,
 1772                     pp->p_pid, pp->p_comm, &closed[1]);
 1773         }
 1774         return (0);
 1775 }
 1776 #undef CHECK_UPTO
 1777 
 1778 /*
 1779  * Sets descriptor owner. If the owner is a process, 'pgid'
 1780  * is set to positive value, process ID. If the owner is process group,
 1781  * 'pgid' is set to -pg_id.
 1782  */
 1783 int
 1784 fsetown(struct proc *p, pid_t *pgid, int cmd, const void *data)
 1785 {
 1786         int id = *(int *)data;
 1787         int error;
 1788 
 1789         switch (cmd) {
 1790         case TIOCSPGRP:
 1791                 if (id < 0)
 1792                         return (EINVAL);
 1793                 id = -id;
 1794                 break;
 1795         default:
 1796                 break;
 1797         }
 1798 
 1799         if (id > 0 && !pfind(id))
 1800                 return (ESRCH);
 1801         else if (id < 0 && (error = pgid_in_session(p, -id)))
 1802                 return (error);
 1803 
 1804         *pgid = id;
 1805         return (0);
 1806 }
 1807 
 1808 /*
 1809  * Return descriptor owner information. If the value is positive,
 1810  * it's process ID. If it's negative, it's process group ID and
 1811  * needs the sign removed before use.
 1812  */
 1813 int
 1814 fgetown(struct proc *p, pid_t pgid, int cmd, void *data)
 1815 {
 1816         switch (cmd) {
 1817         case TIOCGPGRP:
 1818                 *(int *)data = -pgid;
 1819                 break;
 1820         default:
 1821                 *(int *)data = pgid;
 1822                 break;
 1823         }
 1824         return (0);
 1825 }
 1826 
 1827 /*
 1828  * Send signal to descriptor owner, either process or process group.
 1829  */
 1830 void
 1831 fownsignal(pid_t pgid, int signo, int code, int band, void *fdescdata)
 1832 {
 1833         struct proc *p1;
 1834         ksiginfo_t ksi;
 1835 
 1836         memset(&ksi, 0, sizeof(ksi));
 1837         ksi.ksi_signo = signo;
 1838         ksi.ksi_code = code;
 1839         ksi.ksi_band = band;
 1840 
 1841         if (pgid > 0 && (p1 = pfind(pgid)))
 1842                 kpsignal(p1, &ksi, fdescdata);
 1843         else if (pgid < 0)
 1844                 kgsignal(-pgid, &ksi, fdescdata);
 1845 }
 1846 
 1847 int
 1848 fdclone(struct proc *p, struct file *fp, int fd, int flag,
 1849     const struct fileops *fops, void *data)
 1850 {
 1851         fp->f_flag = flag;
 1852         fp->f_type = DTYPE_MISC;
 1853         fp->f_ops = fops;
 1854         fp->f_data = data;
 1855 
 1856         curlwp->l_dupfd = fd;
 1857 
 1858         FILE_SET_MATURE(fp);
 1859         FILE_UNUSE(fp, p);
 1860         return EMOVEFD;
 1861 }
 1862 
 1863 /* ARGSUSED */
 1864 int
 1865 fnullop_fcntl(struct file *fp, u_int cmd, void *data, struct proc *p)
 1866 {
 1867         if (cmd == F_SETFL)
 1868                 return 0;
 1869 
 1870         return EOPNOTSUPP;
 1871 }
 1872 
 1873 /* ARGSUSED */
 1874 int
 1875 fnullop_poll(struct file *fp, int which, struct proc *p)
 1876 {
 1877         return 0;
 1878 }
 1879 
 1880 
 1881 /* ARGSUSED */
 1882 int
 1883 fnullop_kqfilter(struct file *fp, struct knote *kn)
 1884 {
 1885 
 1886         return 0;
 1887 }
 1888 
 1889 /* ARGSUSED */
 1890 int
 1891 fbadop_stat(struct file *fp, struct stat *sb, struct proc *p)
 1892 {
 1893         return EOPNOTSUPP;
 1894 }

Cache object: c23d2758fdd45a18280e15f157b7cdeb


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.