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/emulation/dragonfly12/dfbsd12_getdirentries.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 /*-
    2  * Copyright (c) 2005 The DragonFly Project.  All rights reserved.
    3  * 
    4  * This code is derived from software contributed to The DragonFly Project
    5  * by Joerg Sonnenberger <joerg@bec.de>.
    6  * 
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in
   15  *    the documentation and/or other materials provided with the
   16  *    distribution.
   17  * 3. Neither the name of The DragonFly Project nor the names of its
   18  *    contributors may be used to endorse or promote products derived
   19  *    from this software without specific, prior written permission.
   20  * 
   21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
   25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
   27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
   29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   32  * SUCH DAMAGE.
   33  *
   34  * $DragonFly: src/sys/emulation/dragonfly12/dfbsd12_getdirentries.c,v 1.3 2006/09/05 00:55:44 dillon Exp $
   35  */
   36 
   37 #include "opt_compatdf12.h"
   38 
   39 #include <sys/param.h>
   40 #include <sys/dirent.h>
   41 #include <sys/errno.h>
   42 #include <sys/kern_syscall.h>
   43 #include <sys/systm.h>
   44 #include <sys/sysproto.h>
   45 #include <sys/uio.h>
   46 
   47 #include <sys/mplock2.h>
   48 
   49 #define PADDED_SIZE(x)  \
   50         ((sizeof(struct dfbsd12_dirent) + (x) + 1 + 3) & ~3)
   51 #define MAX_NAMELEN     255
   52 
   53 struct dfbsd12_dirent {
   54         uint32_t        df12_d_fileno;
   55         uint16_t        df12_d_reclen;
   56         uint8_t         df12_d_type;
   57         uint8_t         df12_d_namlen;
   58         char            df12_d_name[];
   59 };
   60 
   61 /*
   62  * MPALMOSTSAFE
   63  */
   64 static int
   65 common_getdirentries(long *base, int *result, int fd, char *usr_buf, size_t count)
   66 {
   67         int error, bytes_transfered;
   68         char *buf, *outbuf;
   69         size_t len;
   70         struct dirent *ndp;
   71         struct dfbsd12_dirent *destdp;
   72 
   73         if (count > 16384)
   74                 len = 16384;
   75         else
   76                 len = count;
   77 
   78         buf = kmalloc(len, M_TEMP, M_WAITOK);
   79 
   80         get_mplock();
   81         error = kern_getdirentries(fd, buf, len, base,
   82                                    &bytes_transfered, UIO_SYSSPACE);
   83         rel_mplock();
   84 
   85         if (error) {
   86                 kfree(buf, M_TEMP);
   87                 return(error);
   88         }
   89 
   90         ndp = (struct dirent *)buf;
   91         outbuf = usr_buf;
   92         destdp = kmalloc(PADDED_SIZE(MAX_NAMELEN), M_TEMP, M_WAITOK);
   93 
   94         for (; (char *)ndp < buf + bytes_transfered; ndp = _DIRENT_NEXT(ndp)) {
   95                 if ((char *)_DIRENT_NEXT(ndp) > buf + bytes_transfered)
   96                         break;
   97                 if (ndp->d_namlen > MAX_NAMELEN)
   98                         continue;
   99                 destdp->df12_d_fileno = ndp->d_ino;
  100                 destdp->df12_d_type = ndp->d_type;
  101                 destdp->df12_d_namlen = ndp->d_namlen;
  102                 destdp->df12_d_reclen = PADDED_SIZE(destdp->df12_d_namlen);
  103                 if (destdp->df12_d_reclen > len)
  104                         break; /* XXX can not happen */
  105                 bcopy(ndp->d_name, destdp->df12_d_name, destdp->df12_d_namlen);
  106                 bzero(destdp->df12_d_name + destdp->df12_d_namlen,
  107                     PADDED_SIZE(destdp->df12_d_namlen) - sizeof(*destdp) -
  108                     destdp->df12_d_namlen);
  109                 error = copyout(destdp, outbuf,
  110                     PADDED_SIZE(destdp->df12_d_namlen));
  111                 if (error)
  112                         break;
  113                 outbuf += PADDED_SIZE(destdp->df12_d_namlen);
  114                 len -= PADDED_SIZE(destdp->df12_d_namlen);
  115         }
  116 
  117         kfree(destdp, M_TEMP);
  118         kfree(buf, M_TEMP);
  119         *result = outbuf - usr_buf;
  120         return (0);
  121 }
  122 
  123 /*
  124  * MPSAFE
  125  */
  126 int
  127 sys_dfbsd12_getdirentries(struct dfbsd12_getdirentries_args *uap)
  128 {
  129         long base;
  130         int error;
  131 
  132         error = common_getdirentries(&base, &uap->sysmsg_iresult, uap->fd,
  133                                      uap->buf, uap->count);
  134 
  135         if (error == 0)
  136                 error = copyout(&base, uap->basep, sizeof(*uap->basep));
  137         return (error);
  138 }
  139 
  140 /*
  141  * MPSAFE
  142  */
  143 int
  144 sys_dfbsd12_getdents(struct dfbsd12_getdents_args *uap)
  145 {
  146         return(common_getdirentries(NULL, &uap->sysmsg_iresult, uap->fd,
  147                                     uap->buf, uap->count));
  148 }

Cache object: 3c4c87398c0451cdfc4adbfc736ef020


[ 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.