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/compat/freebsd32/freebsd32_misc.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) 2002 Doug Rabson
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD$");
   29 
   30 #include "opt_compat.h"
   31 
   32 #include <sys/param.h>
   33 #include <sys/systm.h>
   34 #include <sys/bus.h>
   35 #include <sys/clock.h>
   36 #include <sys/exec.h>
   37 #include <sys/fcntl.h>
   38 #include <sys/filedesc.h>
   39 #include <sys/namei.h>
   40 #include <sys/imgact.h>
   41 #include <sys/kernel.h>
   42 #include <sys/limits.h>
   43 #include <sys/lock.h>
   44 #include <sys/malloc.h>
   45 #include <sys/file.h>           /* Must come after sys/malloc.h */
   46 #include <sys/mbuf.h>
   47 #include <sys/mman.h>
   48 #include <sys/module.h>
   49 #include <sys/mount.h>
   50 #include <sys/mutex.h>
   51 #include <sys/proc.h>
   52 #include <sys/reboot.h>
   53 #include <sys/resource.h>
   54 #include <sys/resourcevar.h>
   55 #include <sys/selinfo.h>
   56 #include <sys/eventvar.h>       /* Must come after sys/selinfo.h */
   57 #include <sys/pipe.h>           /* Must come after sys/selinfo.h */
   58 #include <sys/signal.h>
   59 #include <sys/signalvar.h>
   60 #include <sys/socket.h>
   61 #include <sys/socketvar.h>
   62 #include <sys/stat.h>
   63 #include <sys/syscall.h>
   64 #include <sys/syscallsubr.h>
   65 #include <sys/sysctl.h>
   66 #include <sys/sysent.h>
   67 #include <sys/sysproto.h>
   68 #include <sys/thr.h>
   69 #include <sys/unistd.h>
   70 #include <sys/ucontext.h>
   71 #include <sys/vnode.h>
   72 #include <sys/wait.h>
   73 #include <sys/ipc.h>
   74 #include <sys/msg.h>
   75 #include <sys/sem.h>
   76 #include <sys/shm.h>
   77 
   78 #include <vm/vm.h>
   79 #include <vm/vm_kern.h>
   80 #include <vm/vm_param.h>
   81 #include <vm/pmap.h>
   82 #include <vm/vm_map.h>
   83 #include <vm/vm_object.h>
   84 #include <vm/vm_extern.h>
   85 
   86 #include <machine/cpu.h>
   87 
   88 #include <compat/freebsd32/freebsd32_util.h>
   89 #include <compat/freebsd32/freebsd32.h>
   90 #include <compat/freebsd32/freebsd32_ipc.h>
   91 #include <compat/freebsd32/freebsd32_signal.h>
   92 #include <compat/freebsd32/freebsd32_proto.h>
   93 
   94 CTASSERT(sizeof(struct timeval32) == 8);
   95 CTASSERT(sizeof(struct timespec32) == 8);
   96 CTASSERT(sizeof(struct itimerval32) == 16);
   97 CTASSERT(sizeof(struct statfs32) == 256);
   98 CTASSERT(sizeof(struct rusage32) == 72);
   99 CTASSERT(sizeof(struct sigaltstack32) == 12);
  100 CTASSERT(sizeof(struct kevent32) == 20);
  101 CTASSERT(sizeof(struct iovec32) == 8);
  102 CTASSERT(sizeof(struct msghdr32) == 28);
  103 CTASSERT(sizeof(struct stat32) == 96);
  104 CTASSERT(sizeof(struct sigaction32) == 24);
  105 
  106 static int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count);
  107 static int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count);
  108 
  109 int
  110 freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
  111 {
  112         int error, status;
  113         struct rusage32 ru32;
  114         struct rusage ru, *rup;
  115 
  116         if (uap->rusage != NULL)
  117                 rup = &ru;
  118         else
  119                 rup = NULL;
  120         error = kern_wait(td, uap->pid, &status, uap->options, rup);
  121         if (error)
  122                 return (error);
  123         if (uap->status != NULL)
  124                 error = copyout(&status, uap->status, sizeof(status));
  125         if (uap->rusage != NULL && error == 0) {
  126                 TV_CP(ru, ru32, ru_utime);
  127                 TV_CP(ru, ru32, ru_stime);
  128                 CP(ru, ru32, ru_maxrss);
  129                 CP(ru, ru32, ru_ixrss);
  130                 CP(ru, ru32, ru_idrss);
  131                 CP(ru, ru32, ru_isrss);
  132                 CP(ru, ru32, ru_minflt);
  133                 CP(ru, ru32, ru_majflt);
  134                 CP(ru, ru32, ru_nswap);
  135                 CP(ru, ru32, ru_inblock);
  136                 CP(ru, ru32, ru_oublock);
  137                 CP(ru, ru32, ru_msgsnd);
  138                 CP(ru, ru32, ru_msgrcv);
  139                 CP(ru, ru32, ru_nsignals);
  140                 CP(ru, ru32, ru_nvcsw);
  141                 CP(ru, ru32, ru_nivcsw);
  142                 error = copyout(&ru32, uap->rusage, sizeof(ru32));
  143         }
  144         return (error);
  145 }
  146 
  147 #ifdef COMPAT_FREEBSD4
  148 static void
  149 copy_statfs(struct statfs *in, struct statfs32 *out)
  150 {
  151 
  152         statfs_scale_blocks(in, INT32_MAX);
  153         bzero(out, sizeof(*out));
  154         CP(*in, *out, f_bsize);
  155         out->f_iosize = MIN(in->f_iosize, INT32_MAX);
  156         CP(*in, *out, f_blocks);
  157         CP(*in, *out, f_bfree);
  158         CP(*in, *out, f_bavail);
  159         out->f_files = MIN(in->f_files, INT32_MAX);
  160         out->f_ffree = MIN(in->f_ffree, INT32_MAX);
  161         CP(*in, *out, f_fsid);
  162         CP(*in, *out, f_owner);
  163         CP(*in, *out, f_type);
  164         CP(*in, *out, f_flags);
  165         out->f_syncwrites = MIN(in->f_syncwrites, INT32_MAX);
  166         out->f_asyncwrites = MIN(in->f_asyncwrites, INT32_MAX);
  167         strlcpy(out->f_fstypename,
  168               in->f_fstypename, MFSNAMELEN);
  169         strlcpy(out->f_mntonname,
  170               in->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN));
  171         out->f_syncreads = MIN(in->f_syncreads, INT32_MAX);
  172         out->f_asyncreads = MIN(in->f_asyncreads, INT32_MAX);
  173         strlcpy(out->f_mntfromname,
  174               in->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN));
  175 }
  176 #endif
  177 
  178 #ifdef COMPAT_FREEBSD4
  179 int
  180 freebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap)
  181 {
  182         struct statfs *buf, *sp;
  183         struct statfs32 stat32;
  184         size_t count, size;
  185         int error;
  186 
  187         count = uap->bufsize / sizeof(struct statfs32);
  188         size = count * sizeof(struct statfs);
  189         error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags);
  190         if (size > 0) {
  191                 count = td->td_retval[0];
  192                 sp = buf;
  193                 while (count > 0 && error == 0) {
  194                         copy_statfs(sp, &stat32);
  195                         error = copyout(&stat32, uap->buf, sizeof(stat32));
  196                         sp++;
  197                         uap->buf++;
  198                         count--;
  199                 }
  200                 free(buf, M_TEMP);
  201         }
  202         return (error);
  203 }
  204 #endif
  205 
  206 int
  207 freebsd32_sigaltstack(struct thread *td,
  208                       struct freebsd32_sigaltstack_args *uap)
  209 {
  210         struct sigaltstack32 s32;
  211         struct sigaltstack ss, oss, *ssp;
  212         int error;
  213 
  214         if (uap->ss != NULL) {
  215                 error = copyin(uap->ss, &s32, sizeof(s32));
  216                 if (error)
  217                         return (error);
  218                 PTRIN_CP(s32, ss, ss_sp);
  219                 CP(s32, ss, ss_size);
  220                 CP(s32, ss, ss_flags);
  221                 ssp = &ss;
  222         } else
  223                 ssp = NULL;
  224         error = kern_sigaltstack(td, ssp, &oss);
  225         if (error == 0 && uap->oss != NULL) {
  226                 PTROUT_CP(oss, s32, ss_sp);
  227                 CP(oss, s32, ss_size);
  228                 CP(oss, s32, ss_flags);
  229                 error = copyout(&s32, uap->oss, sizeof(s32));
  230         }
  231         return (error);
  232 }
  233 
  234 /*
  235  * Custom version of exec_copyin_args() so that we can translate
  236  * the pointers.
  237  */
  238 static int
  239 freebsd32_exec_copyin_args(struct image_args *args, char *fname,
  240     enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv)
  241 {
  242         char *argp, *envp;
  243         u_int32_t *p32, arg;
  244         size_t length;
  245         int error;
  246 
  247         bzero(args, sizeof(*args));
  248         if (argv == NULL)
  249                 return (EFAULT);
  250 
  251         /*
  252          * Allocate temporary demand zeroed space for argument and
  253          *      environment strings
  254          */
  255         args->buf = (char *) kmem_alloc_wait(exec_map,
  256             PATH_MAX + ARG_MAX + MAXSHELLCMDLEN);
  257         if (args->buf == NULL)
  258                 return (ENOMEM);
  259         args->begin_argv = args->buf;
  260         args->endp = args->begin_argv;
  261         args->stringspace = ARG_MAX;
  262 
  263         args->fname = args->buf + ARG_MAX;
  264 
  265         /*
  266          * Copy the file name.
  267          */
  268         error = (segflg == UIO_SYSSPACE) ?
  269             copystr(fname, args->fname, PATH_MAX, &length) :
  270             copyinstr(fname, args->fname, PATH_MAX, &length);
  271         if (error != 0)
  272                 goto err_exit;
  273 
  274         /*
  275          * extract arguments first
  276          */
  277         p32 = argv;
  278         for (;;) {
  279                 error = copyin(p32++, &arg, sizeof(arg));
  280                 if (error)
  281                         goto err_exit;
  282                 if (arg == 0)
  283                         break;
  284                 argp = PTRIN(arg);
  285                 error = copyinstr(argp, args->endp, args->stringspace, &length);
  286                 if (error) {
  287                         if (error == ENAMETOOLONG)
  288                                 error = E2BIG;
  289                         goto err_exit;
  290                 }
  291                 args->stringspace -= length;
  292                 args->endp += length;
  293                 args->argc++;
  294         }
  295                         
  296         args->begin_envv = args->endp;
  297 
  298         /*
  299          * extract environment strings
  300          */
  301         if (envv) {
  302                 p32 = envv;
  303                 for (;;) {
  304                         error = copyin(p32++, &arg, sizeof(arg));
  305                         if (error)
  306                                 goto err_exit;
  307                         if (arg == 0)
  308                                 break;
  309                         envp = PTRIN(arg);
  310                         error = copyinstr(envp, args->endp, args->stringspace,
  311                             &length);
  312                         if (error) {
  313                                 if (error == ENAMETOOLONG)
  314                                         error = E2BIG;
  315                                 goto err_exit;
  316                         }
  317                         args->stringspace -= length;
  318                         args->endp += length;
  319                         args->envc++;
  320                 }
  321         }
  322 
  323         return (0);
  324 
  325 err_exit:
  326         kmem_free_wakeup(exec_map, (vm_offset_t)args->buf,
  327             PATH_MAX + ARG_MAX + MAXSHELLCMDLEN);
  328         args->buf = NULL;
  329         return (error);
  330 }
  331 
  332 int
  333 freebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap)
  334 {
  335         struct image_args eargs;
  336         int error;
  337 
  338         error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE,
  339             uap->argv, uap->envv);
  340         if (error == 0)
  341                 error = kern_execve(td, &eargs, NULL);
  342         return (error);
  343 }
  344 
  345 #ifdef __ia64__
  346 static int
  347 freebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end,
  348                        int prot, int fd, off_t pos)
  349 {
  350         vm_map_t map;
  351         vm_map_entry_t entry;
  352         int rv;
  353 
  354         map = &td->td_proc->p_vmspace->vm_map;
  355         if (fd != -1)
  356                 prot |= VM_PROT_WRITE;
  357 
  358         if (vm_map_lookup_entry(map, start, &entry)) {
  359                 if ((entry->protection & prot) != prot) {
  360                         rv = vm_map_protect(map,
  361                                             trunc_page(start),
  362                                             round_page(end),
  363                                             entry->protection | prot,
  364                                             FALSE);
  365                         if (rv != KERN_SUCCESS)
  366                                 return (EINVAL);
  367                 }
  368         } else {
  369                 vm_offset_t addr = trunc_page(start);
  370                 rv = vm_map_find(map, 0, 0,
  371                                  &addr, PAGE_SIZE, FALSE, prot,
  372                                  VM_PROT_ALL, 0);
  373                 if (rv != KERN_SUCCESS)
  374                         return (EINVAL);
  375         }
  376 
  377         if (fd != -1) {
  378                 struct pread_args r;
  379                 r.fd = fd;
  380                 r.buf = (void *) start;
  381                 r.nbyte = end - start;
  382                 r.offset = pos;
  383                 return (pread(td, &r));
  384         } else {
  385                 while (start < end) {
  386                         subyte((void *) start, 0);
  387                         start++;
  388                 }
  389                 return (0);
  390         }
  391 }
  392 #endif
  393 
  394 int
  395 freebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
  396 {
  397         struct mmap_args ap;
  398         vm_offset_t addr = (vm_offset_t) uap->addr;
  399         vm_size_t len    = uap->len;
  400         int prot         = uap->prot;
  401         int flags        = uap->flags;
  402         int fd           = uap->fd;
  403         off_t pos        = (uap->poslo
  404                             | ((off_t)uap->poshi << 32));
  405 #ifdef __ia64__
  406         vm_size_t pageoff;
  407         int error;
  408 
  409         /*
  410          * Attempt to handle page size hassles.
  411          */
  412         pageoff = (pos & PAGE_MASK);
  413         if (flags & MAP_FIXED) {
  414                 vm_offset_t start, end;
  415                 start = addr;
  416                 end = addr + len;
  417 
  418                 if (start != trunc_page(start)) {
  419                         error = freebsd32_mmap_partial(td, start,
  420                                                        round_page(start), prot,
  421                                                        fd, pos);
  422                         if (fd != -1)
  423                                 pos += round_page(start) - start;
  424                         start = round_page(start);
  425                 }
  426                 if (end != round_page(end)) {
  427                         vm_offset_t t = trunc_page(end);
  428                         error = freebsd32_mmap_partial(td, t, end,
  429                                                   prot, fd,
  430                                                   pos + t - start);
  431                         end = trunc_page(end);
  432                 }
  433                 if (end > start && fd != -1 && (pos & PAGE_MASK)) {
  434                         /*
  435                          * We can't map this region at all. The specified
  436                          * address doesn't have the same alignment as the file
  437                          * position. Fake the mapping by simply reading the
  438                          * entire region into memory. First we need to make
  439                          * sure the region exists.
  440                          */
  441                         vm_map_t map;
  442                         struct pread_args r;
  443                         int rv;
  444 
  445                         prot |= VM_PROT_WRITE;
  446                         map = &td->td_proc->p_vmspace->vm_map;
  447                         rv = vm_map_remove(map, start, end);
  448                         if (rv != KERN_SUCCESS)
  449                                 return (EINVAL);
  450                         rv = vm_map_find(map, 0, 0,
  451                                          &start, end - start, FALSE,
  452                                          prot, VM_PROT_ALL, 0);
  453                         if (rv != KERN_SUCCESS)
  454                                 return (EINVAL);
  455                         r.fd = fd;
  456                         r.buf = (void *) start;
  457                         r.nbyte = end - start;
  458                         r.offset = pos;
  459                         error = pread(td, &r);
  460                         if (error)
  461                                 return (error);
  462 
  463                         td->td_retval[0] = addr;
  464                         return (0);
  465                 }
  466                 if (end == start) {
  467                         /*
  468                          * After dealing with the ragged ends, there
  469                          * might be none left.
  470                          */
  471                         td->td_retval[0] = addr;
  472                         return (0);
  473                 }
  474                 addr = start;
  475                 len = end - start;
  476         }
  477 #endif
  478 
  479         ap.addr = (void *) addr;
  480         ap.len = len;
  481         ap.prot = prot;
  482         ap.flags = flags;
  483         ap.fd = fd;
  484         ap.pos = pos;
  485 
  486         return (mmap(td, &ap));
  487 }
  488 
  489 #ifdef COMPAT_FREEBSD6
  490 int
  491 freebsd6_freebsd32_mmap(struct thread *td, struct freebsd6_freebsd32_mmap_args *uap)
  492 {
  493         struct freebsd32_mmap_args ap;
  494 
  495         ap.addr = uap->addr;
  496         ap.len = uap->len;
  497         ap.prot = uap->prot;
  498         ap.flags = uap->flags;
  499         ap.fd = uap->fd;
  500         ap.poslo = uap->poslo;
  501         ap.poshi = uap->poshi;
  502 
  503         return (freebsd32_mmap(td, &ap));
  504 }
  505 #endif
  506 
  507 int
  508 freebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap)
  509 {
  510         struct itimerval itv, oitv, *itvp;      
  511         struct itimerval32 i32;
  512         int error;
  513 
  514         if (uap->itv != NULL) {
  515                 error = copyin(uap->itv, &i32, sizeof(i32));
  516                 if (error)
  517                         return (error);
  518                 TV_CP(i32, itv, it_interval);
  519                 TV_CP(i32, itv, it_value);
  520                 itvp = &itv;
  521         } else
  522                 itvp = NULL;
  523         error = kern_setitimer(td, uap->which, itvp, &oitv);
  524         if (error || uap->oitv == NULL)
  525                 return (error);
  526         TV_CP(oitv, i32, it_interval);
  527         TV_CP(oitv, i32, it_value);
  528         return (copyout(&i32, uap->oitv, sizeof(i32)));
  529 }
  530 
  531 int
  532 freebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap)
  533 {
  534         struct itimerval itv;
  535         struct itimerval32 i32;
  536         int error;
  537 
  538         error = kern_getitimer(td, uap->which, &itv);
  539         if (error || uap->itv == NULL)
  540                 return (error);
  541         TV_CP(itv, i32, it_interval);
  542         TV_CP(itv, i32, it_value);
  543         return (copyout(&i32, uap->itv, sizeof(i32)));
  544 }
  545 
  546 int
  547 freebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
  548 {
  549         struct timeval32 tv32;
  550         struct timeval tv, *tvp;
  551         int error;
  552 
  553         if (uap->tv != NULL) {
  554                 error = copyin(uap->tv, &tv32, sizeof(tv32));
  555                 if (error)
  556                         return (error);
  557                 CP(tv32, tv, tv_sec);
  558                 CP(tv32, tv, tv_usec);
  559                 tvp = &tv;
  560         } else
  561                 tvp = NULL;
  562         /*
  563          * XXX big-endian needs to convert the fd_sets too.
  564          * XXX Do pointers need PTRIN()?
  565          */
  566         return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp));
  567 }
  568 
  569 /*
  570  * Copy 'count' items into the destination list pointed to by uap->eventlist.
  571  */
  572 static int
  573 freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count)
  574 {
  575         struct freebsd32_kevent_args *uap;
  576         struct kevent32 ks32[KQ_NEVENTS];
  577         int i, error = 0;
  578 
  579         KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
  580         uap = (struct freebsd32_kevent_args *)arg;
  581 
  582         for (i = 0; i < count; i++) {
  583                 CP(kevp[i], ks32[i], ident);
  584                 CP(kevp[i], ks32[i], filter);
  585                 CP(kevp[i], ks32[i], flags);
  586                 CP(kevp[i], ks32[i], fflags);
  587                 CP(kevp[i], ks32[i], data);
  588                 PTROUT_CP(kevp[i], ks32[i], udata);
  589         }
  590         error = copyout(ks32, uap->eventlist, count * sizeof *ks32);
  591         if (error == 0)
  592                 uap->eventlist += count;
  593         return (error);
  594 }
  595 
  596 /*
  597  * Copy 'count' items from the list pointed to by uap->changelist.
  598  */
  599 static int
  600 freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count)
  601 {
  602         struct freebsd32_kevent_args *uap;
  603         struct kevent32 ks32[KQ_NEVENTS];
  604         int i, error = 0;
  605 
  606         KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count));
  607         uap = (struct freebsd32_kevent_args *)arg;
  608 
  609         error = copyin(uap->changelist, ks32, count * sizeof *ks32);
  610         if (error)
  611                 goto done;
  612         uap->changelist += count;
  613 
  614         for (i = 0; i < count; i++) {
  615                 CP(ks32[i], kevp[i], ident);
  616                 CP(ks32[i], kevp[i], filter);
  617                 CP(ks32[i], kevp[i], flags);
  618                 CP(ks32[i], kevp[i], fflags);
  619                 CP(ks32[i], kevp[i], data);
  620                 PTRIN_CP(ks32[i], kevp[i], udata);
  621         }
  622 done:
  623         return (error);
  624 }
  625 
  626 int
  627 freebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap)
  628 {
  629         struct timespec32 ts32;
  630         struct timespec ts, *tsp;
  631         struct kevent_copyops k_ops = { uap,
  632                                         freebsd32_kevent_copyout,
  633                                         freebsd32_kevent_copyin};
  634         int error;
  635 
  636 
  637         if (uap->timeout) {
  638                 error = copyin(uap->timeout, &ts32, sizeof(ts32));
  639                 if (error)
  640                         return (error);
  641                 CP(ts32, ts, tv_sec);
  642                 CP(ts32, ts, tv_nsec);
  643                 tsp = &ts;
  644         } else
  645                 tsp = NULL;
  646         error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents,
  647             &k_ops, tsp);
  648         return (error);
  649 }
  650 
  651 int
  652 freebsd32_gettimeofday(struct thread *td,
  653                        struct freebsd32_gettimeofday_args *uap)
  654 {
  655         struct timeval atv;
  656         struct timeval32 atv32;
  657         struct timezone rtz;
  658         int error = 0;
  659 
  660         if (uap->tp) {
  661                 microtime(&atv);
  662                 CP(atv, atv32, tv_sec);
  663                 CP(atv, atv32, tv_usec);
  664                 error = copyout(&atv32, uap->tp, sizeof (atv32));
  665         }
  666         if (error == 0 && uap->tzp != NULL) {
  667                 rtz.tz_minuteswest = tz_minuteswest;
  668                 rtz.tz_dsttime = tz_dsttime;
  669                 error = copyout(&rtz, uap->tzp, sizeof (rtz));
  670         }
  671         return (error);
  672 }
  673 
  674 int
  675 freebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap)
  676 {
  677         struct rusage32 s32;
  678         struct rusage s;
  679         int error;
  680 
  681         error = kern_getrusage(td, uap->who, &s);
  682         if (error)
  683                 return (error);
  684         if (uap->rusage != NULL) {
  685                 TV_CP(s, s32, ru_utime);
  686                 TV_CP(s, s32, ru_stime);
  687                 CP(s, s32, ru_maxrss);
  688                 CP(s, s32, ru_ixrss);
  689                 CP(s, s32, ru_idrss);
  690                 CP(s, s32, ru_isrss);
  691                 CP(s, s32, ru_minflt);
  692                 CP(s, s32, ru_majflt);
  693                 CP(s, s32, ru_nswap);
  694                 CP(s, s32, ru_inblock);
  695                 CP(s, s32, ru_oublock);
  696                 CP(s, s32, ru_msgsnd);
  697                 CP(s, s32, ru_msgrcv);
  698                 CP(s, s32, ru_nsignals);
  699                 CP(s, s32, ru_nvcsw);
  700                 CP(s, s32, ru_nivcsw);
  701                 error = copyout(&s32, uap->rusage, sizeof(s32));
  702         }
  703         return (error);
  704 }
  705 
  706 static int
  707 freebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop)
  708 {
  709         struct iovec32 iov32;
  710         struct iovec *iov;
  711         struct uio *uio;
  712         u_int iovlen;
  713         int error, i;
  714 
  715         *uiop = NULL;
  716         if (iovcnt > UIO_MAXIOV)
  717                 return (EINVAL);
  718         iovlen = iovcnt * sizeof(struct iovec);
  719         uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK);
  720         iov = (struct iovec *)(uio + 1);
  721         for (i = 0; i < iovcnt; i++) {
  722                 error = copyin(&iovp[i], &iov32, sizeof(struct iovec32));
  723                 if (error) {
  724                         free(uio, M_IOV);
  725                         return (error);
  726                 }
  727                 iov[i].iov_base = PTRIN(iov32.iov_base);
  728                 iov[i].iov_len = iov32.iov_len;
  729         }
  730         uio->uio_iov = iov;
  731         uio->uio_iovcnt = iovcnt;
  732         uio->uio_segflg = UIO_USERSPACE;
  733         uio->uio_offset = -1;
  734         uio->uio_resid = 0;
  735         for (i = 0; i < iovcnt; i++) {
  736                 if (iov->iov_len > INT_MAX - uio->uio_resid) {
  737                         free(uio, M_IOV);
  738                         return (EINVAL);
  739                 }
  740                 uio->uio_resid += iov->iov_len;
  741                 iov++;
  742         }
  743         *uiop = uio;
  744         return (0);
  745 }
  746 
  747 int
  748 freebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap)
  749 {
  750         struct uio *auio;
  751         int error;
  752 
  753         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
  754         if (error)
  755                 return (error);
  756         error = kern_readv(td, uap->fd, auio);
  757         free(auio, M_IOV);
  758         return (error);
  759 }
  760 
  761 int
  762 freebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap)
  763 {
  764         struct uio *auio;
  765         int error;
  766 
  767         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
  768         if (error)
  769                 return (error);
  770         error = kern_writev(td, uap->fd, auio);
  771         free(auio, M_IOV);
  772         return (error);
  773 }
  774 
  775 int
  776 freebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap)
  777 {
  778         struct uio *auio;
  779         int error;
  780 
  781         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
  782         if (error)
  783                 return (error);
  784         error = kern_preadv(td, uap->fd, auio, uap->offset);
  785         free(auio, M_IOV);
  786         return (error);
  787 }
  788 
  789 int
  790 freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap)
  791 {
  792         struct uio *auio;
  793         int error;
  794 
  795         error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
  796         if (error)
  797                 return (error);
  798         error = kern_pwritev(td, uap->fd, auio, uap->offset);
  799         free(auio, M_IOV);
  800         return (error);
  801 }
  802 
  803 static int
  804 freebsd32_copyiniov(struct iovec32 *iovp32, u_int iovcnt, struct iovec **iovp,
  805     int error)
  806 {
  807         struct iovec32 iov32;
  808         struct iovec *iov;
  809         u_int iovlen;
  810         int i;
  811 
  812         *iovp = NULL;
  813         if (iovcnt > UIO_MAXIOV)
  814                 return (error);
  815         iovlen = iovcnt * sizeof(struct iovec);
  816         iov = malloc(iovlen, M_IOV, M_WAITOK);
  817         for (i = 0; i < iovcnt; i++) {
  818                 error = copyin(&iovp32[i], &iov32, sizeof(struct iovec32));
  819                 if (error) {
  820                         free(iov, M_IOV);
  821                         return (error);
  822                 }
  823                 iov[i].iov_base = PTRIN(iov32.iov_base);
  824                 iov[i].iov_len = iov32.iov_len;
  825         }
  826         *iovp = iov;
  827         return (0);
  828 }
  829 
  830 static int
  831 freebsd32_copyinmsghdr(struct msghdr32 *msg32, struct msghdr *msg)
  832 {
  833         struct msghdr32 m32;
  834         int error;
  835 
  836         error = copyin(msg32, &m32, sizeof(m32));
  837         if (error)
  838                 return (error);
  839         msg->msg_name = PTRIN(m32.msg_name);
  840         msg->msg_namelen = m32.msg_namelen;
  841         msg->msg_iov = PTRIN(m32.msg_iov);
  842         msg->msg_iovlen = m32.msg_iovlen;
  843         msg->msg_control = PTRIN(m32.msg_control);
  844         msg->msg_controllen = m32.msg_controllen;
  845         msg->msg_flags = m32.msg_flags;
  846         return (0);
  847 }
  848 
  849 static int
  850 freebsd32_copyoutmsghdr(struct msghdr *msg, struct msghdr32 *msg32)
  851 {
  852         struct msghdr32 m32;
  853         int error;
  854 
  855         m32.msg_name = PTROUT(msg->msg_name);
  856         m32.msg_namelen = msg->msg_namelen;
  857         m32.msg_iov = PTROUT(msg->msg_iov);
  858         m32.msg_iovlen = msg->msg_iovlen;
  859         m32.msg_control = PTROUT(msg->msg_control);
  860         m32.msg_controllen = msg->msg_controllen;
  861         m32.msg_flags = msg->msg_flags;
  862         error = copyout(&m32, msg32, sizeof(m32));
  863         return (error);
  864 }
  865 
  866 #define FREEBSD32_ALIGNBYTES    (sizeof(int) - 1)
  867 #define FREEBSD32_ALIGN(p)      \
  868         (((u_long)(p) + FREEBSD32_ALIGNBYTES) & ~FREEBSD32_ALIGNBYTES)
  869 #define FREEBSD32_CMSG_SPACE(l) \
  870         (FREEBSD32_ALIGN(sizeof(struct cmsghdr)) + FREEBSD32_ALIGN(l))
  871 
  872 #define FREEBSD32_CMSG_DATA(cmsg)       ((unsigned char *)(cmsg) + \
  873                                  FREEBSD32_ALIGN(sizeof(struct cmsghdr)))
  874 static int
  875 freebsd32_copy_msg_out(struct msghdr *msg, struct mbuf *control)
  876 {
  877         struct cmsghdr *cm;
  878         void *data;
  879         socklen_t clen, datalen;
  880         int error;
  881         caddr_t ctlbuf;
  882         int len, maxlen, copylen;
  883         struct mbuf *m;
  884         error = 0;
  885 
  886         len    = msg->msg_controllen;
  887         maxlen = msg->msg_controllen;
  888         msg->msg_controllen = 0;
  889 
  890         m = control;
  891         ctlbuf = msg->msg_control;
  892       
  893         while (m && len > 0) {
  894                 cm = mtod(m, struct cmsghdr *);
  895                 clen = m->m_len;
  896 
  897                 while (cm != NULL) {
  898 
  899                         if (sizeof(struct cmsghdr) > clen ||
  900                             cm->cmsg_len > clen) {
  901                                 error = EINVAL;
  902                                 break;
  903                         }       
  904 
  905                         data   = CMSG_DATA(cm);
  906                         datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
  907 
  908                         /* Adjust message length */
  909                         cm->cmsg_len = FREEBSD32_ALIGN(sizeof(struct cmsghdr)) +
  910                             datalen;
  911 
  912 
  913                         /* Copy cmsghdr */
  914                         copylen = sizeof(struct cmsghdr);
  915                         if (len < copylen) {
  916                                 msg->msg_flags |= MSG_CTRUNC;
  917                                 copylen = len;
  918                         }
  919 
  920                         error = copyout(cm,ctlbuf,copylen);
  921                         if (error)
  922                                 goto exit;
  923 
  924                         ctlbuf += FREEBSD32_ALIGN(copylen);
  925                         len    -= FREEBSD32_ALIGN(copylen);
  926 
  927                         if (len <= 0)
  928                                 break;
  929 
  930                         /* Copy data */
  931                         copylen = datalen;
  932                         if (len < copylen) {
  933                                 msg->msg_flags |= MSG_CTRUNC;
  934                                 copylen = len;
  935                         }
  936 
  937                         error = copyout(data,ctlbuf,copylen);
  938                         if (error)
  939                                 goto exit;
  940 
  941                         ctlbuf += FREEBSD32_ALIGN(copylen);
  942                         len    -= FREEBSD32_ALIGN(copylen);
  943 
  944                         if (CMSG_SPACE(datalen) < clen) {
  945                                 clen -= CMSG_SPACE(datalen);
  946                                 cm = (struct cmsghdr *)
  947                                         ((caddr_t)cm + CMSG_SPACE(datalen));
  948                         } else {
  949                                 clen = 0;
  950                                 cm = NULL;
  951                         }
  952                 }       
  953                 m = m->m_next;
  954         }
  955 
  956         msg->msg_controllen = (len <= 0) ? maxlen :  ctlbuf - (caddr_t)msg->msg_control;
  957         
  958 exit:
  959         return (error);
  960 
  961 }
  962 
  963 int
  964 freebsd32_recvmsg(td, uap)
  965         struct thread *td;
  966         struct freebsd32_recvmsg_args /* {
  967                 int     s;
  968                 struct  msghdr32 *msg;
  969                 int     flags;
  970         } */ *uap;
  971 {
  972         struct msghdr msg;
  973         struct msghdr32 m32;
  974         struct iovec *uiov, *iov;
  975         struct mbuf *control = NULL;
  976         struct mbuf **controlp;
  977 
  978         int error;
  979         error = copyin(uap->msg, &m32, sizeof(m32));
  980         if (error)
  981                 return (error);
  982         error = freebsd32_copyinmsghdr(uap->msg, &msg);
  983         if (error)
  984                 return (error);
  985         error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov,
  986             EMSGSIZE);
  987         if (error)
  988                 return (error);
  989         msg.msg_flags = uap->flags;
  990         uiov = msg.msg_iov;
  991         msg.msg_iov = iov;
  992 
  993         controlp = (msg.msg_control != NULL) ?  &control : NULL;
  994         error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, controlp);
  995         if (error == 0) {
  996                 msg.msg_iov = uiov;
  997                 
  998                 if (control != NULL)
  999                         error = freebsd32_copy_msg_out(&msg, control);
 1000                 
 1001                 if (error == 0)
 1002                         error = freebsd32_copyoutmsghdr(&msg, uap->msg);
 1003         }
 1004         free(iov, M_IOV);
 1005 
 1006         if (control != NULL)
 1007                 m_freem(control);
 1008 
 1009         return (error);
 1010 }
 1011 
 1012 
 1013 static int
 1014 freebsd32_convert_msg_in(struct mbuf **controlp)
 1015 {
 1016         struct mbuf *control = *controlp;
 1017         struct cmsghdr *cm = mtod(control, struct cmsghdr *);
 1018         void *data;
 1019         socklen_t clen = control->m_len, datalen;
 1020         int error;
 1021 
 1022         error = 0;
 1023         *controlp = NULL;
 1024 
 1025         while (cm != NULL) {
 1026                 if (sizeof(struct cmsghdr) > clen || cm->cmsg_len > clen) {
 1027                         error = EINVAL;
 1028                         break;
 1029                 }
 1030 
 1031                 data = FREEBSD32_CMSG_DATA(cm);
 1032                 datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
 1033 
 1034                 *controlp = sbcreatecontrol(data, datalen, cm->cmsg_type,
 1035                     cm->cmsg_level);
 1036                 controlp = &(*controlp)->m_next;
 1037 
 1038                 if (FREEBSD32_CMSG_SPACE(datalen) < clen) {
 1039                         clen -= FREEBSD32_CMSG_SPACE(datalen);
 1040                         cm = (struct cmsghdr *)
 1041                                 ((caddr_t)cm + FREEBSD32_CMSG_SPACE(datalen));
 1042                 } else {
 1043                         clen = 0;
 1044                         cm = NULL;
 1045                 }
 1046         }
 1047 
 1048         m_freem(control);
 1049         return (error);
 1050 }
 1051 
 1052 
 1053 int
 1054 freebsd32_sendmsg(struct thread *td,
 1055                   struct freebsd32_sendmsg_args *uap)
 1056 {
 1057         struct msghdr msg;
 1058         struct msghdr32 m32;
 1059         struct iovec *iov;
 1060         struct mbuf *control = NULL;
 1061         struct sockaddr *to = NULL;
 1062         int error;
 1063 
 1064         error = copyin(uap->msg, &m32, sizeof(m32));
 1065         if (error)
 1066                 return (error);
 1067         error = freebsd32_copyinmsghdr(uap->msg, &msg);
 1068         if (error)
 1069                 return (error);
 1070         error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov,
 1071             EMSGSIZE);
 1072         if (error)
 1073                 return (error);
 1074         msg.msg_iov = iov;
 1075         if (msg.msg_name != NULL) {
 1076                 error = getsockaddr(&to, msg.msg_name, msg.msg_namelen);
 1077                 if (error) {
 1078                         to = NULL;
 1079                         goto out;
 1080                 }
 1081                 msg.msg_name = to;
 1082         }
 1083 
 1084         if (msg.msg_control) {
 1085                 if (msg.msg_controllen < sizeof(struct cmsghdr)) {
 1086                         error = EINVAL;
 1087                         goto out;
 1088                 }
 1089 
 1090                 error = sockargs(&control, msg.msg_control,
 1091                     msg.msg_controllen, MT_CONTROL);
 1092                 if (error)
 1093                         goto out;
 1094                 
 1095                 error = freebsd32_convert_msg_in(&control);
 1096                 if (error)
 1097                         goto out;
 1098         }
 1099 
 1100         error = kern_sendit(td, uap->s, &msg, uap->flags, control,
 1101             UIO_USERSPACE);
 1102 
 1103 out:
 1104         free(iov, M_IOV);
 1105         if (to)
 1106                 free(to, M_SONAME);
 1107         return (error);
 1108 }
 1109 
 1110 int
 1111 freebsd32_recvfrom(struct thread *td,
 1112                    struct freebsd32_recvfrom_args *uap)
 1113 {
 1114         struct msghdr msg;
 1115         struct iovec aiov;
 1116         int error;
 1117 
 1118         if (uap->fromlenaddr) {
 1119                 error = copyin(PTRIN(uap->fromlenaddr), &msg.msg_namelen,
 1120                     sizeof(msg.msg_namelen));
 1121                 if (error)
 1122                         return (error);
 1123         } else {
 1124                 msg.msg_namelen = 0;
 1125         }
 1126 
 1127         msg.msg_name = PTRIN(uap->from);
 1128         msg.msg_iov = &aiov;
 1129         msg.msg_iovlen = 1;
 1130         aiov.iov_base = PTRIN(uap->buf);
 1131         aiov.iov_len = uap->len;
 1132         msg.msg_control = NULL;
 1133         msg.msg_flags = uap->flags;
 1134         error = kern_recvit(td, uap->s, &msg, UIO_USERSPACE, NULL);
 1135         if (error == 0 && uap->fromlenaddr)
 1136                 error = copyout(&msg.msg_namelen, PTRIN(uap->fromlenaddr),
 1137                     sizeof (msg.msg_namelen));
 1138         return (error);
 1139 }
 1140 
 1141 int
 1142 freebsd32_settimeofday(struct thread *td,
 1143                        struct freebsd32_settimeofday_args *uap)
 1144 {
 1145         struct timeval32 tv32;
 1146         struct timeval tv, *tvp;
 1147         struct timezone tz, *tzp;
 1148         int error;
 1149 
 1150         if (uap->tv) {
 1151                 error = copyin(uap->tv, &tv32, sizeof(tv32));
 1152                 if (error)
 1153                         return (error);
 1154                 CP(tv32, tv, tv_sec);
 1155                 CP(tv32, tv, tv_usec);
 1156                 tvp = &tv;
 1157         } else
 1158                 tvp = NULL;
 1159         if (uap->tzp) {
 1160                 error = copyin(uap->tzp, &tz, sizeof(tz));
 1161                 if (error)
 1162                         return (error);
 1163                 tzp = &tz;
 1164         } else
 1165                 tzp = NULL;
 1166         return (kern_settimeofday(td, tvp, tzp));
 1167 }
 1168 
 1169 int
 1170 freebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap)
 1171 {
 1172         struct timeval32 s32[2];
 1173         struct timeval s[2], *sp;
 1174         int error;
 1175 
 1176         if (uap->tptr != NULL) {
 1177                 error = copyin(uap->tptr, s32, sizeof(s32));
 1178                 if (error)
 1179                         return (error);
 1180                 CP(s32[0], s[0], tv_sec);
 1181                 CP(s32[0], s[0], tv_usec);
 1182                 CP(s32[1], s[1], tv_sec);
 1183                 CP(s32[1], s[1], tv_usec);
 1184                 sp = s;
 1185         } else
 1186                 sp = NULL;
 1187         return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE));
 1188 }
 1189 
 1190 int
 1191 freebsd32_lutimes(struct thread *td, struct freebsd32_lutimes_args *uap)
 1192 {
 1193         struct timeval32 s32[2];
 1194         struct timeval s[2], *sp;
 1195         int error;
 1196 
 1197         if (uap->tptr != NULL) {
 1198                 error = copyin(uap->tptr, s32, sizeof(s32));
 1199                 if (error)
 1200                         return (error);
 1201                 CP(s32[0], s[0], tv_sec);
 1202                 CP(s32[0], s[0], tv_usec);
 1203                 CP(s32[1], s[1], tv_sec);
 1204                 CP(s32[1], s[1], tv_usec);
 1205                 sp = s;
 1206         } else
 1207                 sp = NULL;
 1208         return (kern_lutimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE));
 1209 }
 1210 
 1211 int
 1212 freebsd32_futimes(struct thread *td, struct freebsd32_futimes_args *uap)
 1213 {
 1214         struct timeval32 s32[2];
 1215         struct timeval s[2], *sp;
 1216         int error;
 1217 
 1218         if (uap->tptr != NULL) {
 1219                 error = copyin(uap->tptr, s32, sizeof(s32));
 1220                 if (error)
 1221                         return (error);
 1222                 CP(s32[0], s[0], tv_sec);
 1223                 CP(s32[0], s[0], tv_usec);
 1224                 CP(s32[1], s[1], tv_sec);
 1225                 CP(s32[1], s[1], tv_usec);
 1226                 sp = s;
 1227         } else
 1228                 sp = NULL;
 1229         return (kern_futimes(td, uap->fd, sp, UIO_SYSSPACE));
 1230 }
 1231 
 1232 
 1233 int
 1234 freebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap)
 1235 {
 1236         struct timeval32 tv32;
 1237         struct timeval delta, olddelta, *deltap;
 1238         int error;
 1239 
 1240         if (uap->delta) {
 1241                 error = copyin(uap->delta, &tv32, sizeof(tv32));
 1242                 if (error)
 1243                         return (error);
 1244                 CP(tv32, delta, tv_sec);
 1245                 CP(tv32, delta, tv_usec);
 1246                 deltap = &delta;
 1247         } else
 1248                 deltap = NULL;
 1249         error = kern_adjtime(td, deltap, &olddelta);
 1250         if (uap->olddelta && error == 0) {
 1251                 CP(olddelta, tv32, tv_sec);
 1252                 CP(olddelta, tv32, tv_usec);
 1253                 error = copyout(&tv32, uap->olddelta, sizeof(tv32));
 1254         }
 1255         return (error);
 1256 }
 1257 
 1258 #ifdef COMPAT_FREEBSD4
 1259 int
 1260 freebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap)
 1261 {
 1262         struct statfs32 s32;
 1263         struct statfs s;
 1264         int error;
 1265 
 1266         error = kern_statfs(td, uap->path, UIO_USERSPACE, &s);
 1267         if (error)
 1268                 return (error);
 1269         copy_statfs(&s, &s32);
 1270         return (copyout(&s32, uap->buf, sizeof(s32)));
 1271 }
 1272 #endif
 1273 
 1274 #ifdef COMPAT_FREEBSD4
 1275 int
 1276 freebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap)
 1277 {
 1278         struct statfs32 s32;
 1279         struct statfs s;
 1280         int error;
 1281 
 1282         error = kern_fstatfs(td, uap->fd, &s);
 1283         if (error)
 1284                 return (error);
 1285         copy_statfs(&s, &s32);
 1286         return (copyout(&s32, uap->buf, sizeof(s32)));
 1287 }
 1288 #endif
 1289 
 1290 #ifdef COMPAT_FREEBSD4
 1291 int
 1292 freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap)
 1293 {
 1294         struct statfs32 s32;
 1295         struct statfs s;
 1296         fhandle_t fh;
 1297         int error;
 1298 
 1299         if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0)
 1300                 return (error);
 1301         error = kern_fhstatfs(td, fh, &s);
 1302         if (error)
 1303                 return (error);
 1304         copy_statfs(&s, &s32);
 1305         return (copyout(&s32, uap->buf, sizeof(s32)));
 1306 }
 1307 #endif
 1308 
 1309 static void
 1310 freebsd32_ipcperm_in(struct ipc_perm32 *ip32, struct ipc_perm *ip)
 1311 {
 1312 
 1313         CP(*ip32, *ip, cuid);
 1314         CP(*ip32, *ip, cgid);
 1315         CP(*ip32, *ip, uid);
 1316         CP(*ip32, *ip, gid);
 1317         CP(*ip32, *ip, mode);
 1318         CP(*ip32, *ip, seq);
 1319         CP(*ip32, *ip, key);
 1320 }
 1321 
 1322 static void
 1323 freebsd32_ipcperm_out(struct ipc_perm *ip, struct ipc_perm32 *ip32)
 1324 {
 1325 
 1326         CP(*ip, *ip32, cuid);
 1327         CP(*ip, *ip32, cgid);
 1328         CP(*ip, *ip32, uid);
 1329         CP(*ip, *ip32, gid);
 1330         CP(*ip, *ip32, mode);
 1331         CP(*ip, *ip32, seq);
 1332         CP(*ip, *ip32, key);
 1333 }
 1334 
 1335 int
 1336 freebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
 1337 {
 1338 
 1339         switch (uap->which) {
 1340         case 0:
 1341                 return (freebsd32_semctl(td,
 1342                     (struct freebsd32_semctl_args *)&uap->a2));
 1343         default:
 1344                 return (semsys(td, (struct semsys_args *)uap));
 1345         }
 1346 }
 1347 
 1348 int
 1349 freebsd32_semctl(struct thread *td, struct freebsd32_semctl_args *uap)
 1350 {
 1351         struct semid_ds32 dsbuf32;
 1352         struct semid_ds dsbuf;
 1353         union semun semun;
 1354         union semun32 arg;
 1355         register_t rval;
 1356         int error;
 1357 
 1358         switch (uap->cmd) {
 1359         case SEM_STAT:
 1360         case IPC_SET:
 1361         case IPC_STAT:
 1362         case GETALL:
 1363         case SETVAL:
 1364         case SETALL:
 1365                 error = copyin(uap->arg, &arg, sizeof(arg));
 1366                 if (error)
 1367                         return (error);         
 1368                 break;
 1369         }
 1370 
 1371         switch (uap->cmd) {
 1372         case SEM_STAT:
 1373         case IPC_STAT:
 1374                 semun.buf = &dsbuf;
 1375                 break;
 1376         case IPC_SET:
 1377                 error = copyin(PTRIN(arg.buf), &dsbuf32, sizeof(dsbuf32));
 1378                 if (error)
 1379                         return (error);
 1380                 freebsd32_ipcperm_in(&dsbuf32.sem_perm, &dsbuf.sem_perm);
 1381                 PTRIN_CP(dsbuf32, dsbuf, sem_base);
 1382                 CP(dsbuf32, dsbuf, sem_nsems);
 1383                 CP(dsbuf32, dsbuf, sem_otime);
 1384                 CP(dsbuf32, dsbuf, sem_pad1);
 1385                 CP(dsbuf32, dsbuf, sem_ctime);
 1386                 CP(dsbuf32, dsbuf, sem_pad2);
 1387                 CP(dsbuf32, dsbuf, sem_pad3[0]);
 1388                 CP(dsbuf32, dsbuf, sem_pad3[1]);
 1389                 CP(dsbuf32, dsbuf, sem_pad3[2]);
 1390                 CP(dsbuf32, dsbuf, sem_pad3[3]);
 1391                 semun.buf = &dsbuf;
 1392                 break;
 1393         case GETALL:
 1394         case SETALL:
 1395                 semun.array = PTRIN(arg.array);
 1396                 break;
 1397         case SETVAL:
 1398                 semun.val = arg.val;
 1399                 break;          
 1400         }
 1401 
 1402         error = kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &semun,
 1403             &rval);
 1404         if (error)
 1405                 return (error);
 1406 
 1407         switch (uap->cmd) {
 1408         case SEM_STAT:
 1409         case IPC_STAT:
 1410                 freebsd32_ipcperm_out(&dsbuf.sem_perm, &dsbuf32.sem_perm);
 1411                 PTROUT_CP(dsbuf, dsbuf32, sem_base);
 1412                 CP(dsbuf, dsbuf32, sem_nsems);
 1413                 CP(dsbuf, dsbuf32, sem_otime);
 1414                 CP(dsbuf, dsbuf32, sem_pad1);
 1415                 CP(dsbuf, dsbuf32, sem_ctime);
 1416                 CP(dsbuf, dsbuf32, sem_pad2);
 1417                 CP(dsbuf, dsbuf32, sem_pad3[0]);
 1418                 CP(dsbuf, dsbuf32, sem_pad3[1]);
 1419                 CP(dsbuf, dsbuf32, sem_pad3[2]);
 1420                 CP(dsbuf, dsbuf32, sem_pad3[3]);
 1421                 error = copyout(&dsbuf32, PTRIN(arg.buf), sizeof(dsbuf32));
 1422                 break;
 1423         }
 1424 
 1425         if (error == 0)
 1426                 td->td_retval[0] = rval;
 1427         return (error);
 1428 }
 1429 
 1430 int
 1431 freebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap)
 1432 {
 1433 
 1434         switch (uap->which) {
 1435         case 0:
 1436                 return (freebsd32_msgctl(td,
 1437                     (struct freebsd32_msgctl_args *)&uap->a2));
 1438         case 2:
 1439                 return (freebsd32_msgsnd(td,
 1440                     (struct freebsd32_msgsnd_args *)&uap->a2));
 1441         case 3:
 1442                 return (freebsd32_msgrcv(td,
 1443                     (struct freebsd32_msgrcv_args *)&uap->a2));
 1444         default:
 1445                 return (msgsys(td, (struct msgsys_args *)uap));
 1446         }
 1447 }
 1448 
 1449 int
 1450 freebsd32_msgctl(struct thread *td, struct freebsd32_msgctl_args *uap)
 1451 {
 1452         struct msqid_ds msqbuf;
 1453         struct msqid_ds32 msqbuf32;
 1454         int error;
 1455 
 1456         if (uap->cmd == IPC_SET) {
 1457                 error = copyin(uap->buf, &msqbuf32, sizeof(msqbuf32));
 1458                 if (error)
 1459                         return (error);
 1460                 freebsd32_ipcperm_in(&msqbuf32.msg_perm, &msqbuf.msg_perm);
 1461                 PTRIN_CP(msqbuf32, msqbuf, msg_first);
 1462                 PTRIN_CP(msqbuf32, msqbuf, msg_last);
 1463                 CP(msqbuf32, msqbuf, msg_cbytes);
 1464                 CP(msqbuf32, msqbuf, msg_qnum);
 1465                 CP(msqbuf32, msqbuf, msg_qbytes);
 1466                 CP(msqbuf32, msqbuf, msg_lspid);
 1467                 CP(msqbuf32, msqbuf, msg_lrpid);
 1468                 CP(msqbuf32, msqbuf, msg_stime);
 1469                 CP(msqbuf32, msqbuf, msg_pad1);
 1470                 CP(msqbuf32, msqbuf, msg_rtime);
 1471                 CP(msqbuf32, msqbuf, msg_pad2);
 1472                 CP(msqbuf32, msqbuf, msg_ctime);
 1473                 CP(msqbuf32, msqbuf, msg_pad3);
 1474                 CP(msqbuf32, msqbuf, msg_pad4[0]);
 1475                 CP(msqbuf32, msqbuf, msg_pad4[1]);
 1476                 CP(msqbuf32, msqbuf, msg_pad4[2]);
 1477                 CP(msqbuf32, msqbuf, msg_pad4[3]);
 1478         }
 1479         error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf);
 1480         if (error)
 1481                 return (error);
 1482         if (uap->cmd == IPC_STAT) {
 1483                 freebsd32_ipcperm_out(&msqbuf.msg_perm, &msqbuf32.msg_perm);
 1484                 PTROUT_CP(msqbuf, msqbuf32, msg_first);
 1485                 PTROUT_CP(msqbuf, msqbuf32, msg_last);
 1486                 CP(msqbuf, msqbuf32, msg_cbytes);
 1487                 CP(msqbuf, msqbuf32, msg_qnum);
 1488                 CP(msqbuf, msqbuf32, msg_qbytes);
 1489                 CP(msqbuf, msqbuf32, msg_lspid);
 1490                 CP(msqbuf, msqbuf32, msg_lrpid);
 1491                 CP(msqbuf, msqbuf32, msg_stime);
 1492                 CP(msqbuf, msqbuf32, msg_pad1);
 1493                 CP(msqbuf, msqbuf32, msg_rtime);
 1494                 CP(msqbuf, msqbuf32, msg_pad2);
 1495                 CP(msqbuf, msqbuf32, msg_ctime);
 1496                 CP(msqbuf, msqbuf32, msg_pad3);
 1497                 CP(msqbuf, msqbuf32, msg_pad4[0]);
 1498                 CP(msqbuf, msqbuf32, msg_pad4[1]);
 1499                 CP(msqbuf, msqbuf32, msg_pad4[2]);
 1500                 CP(msqbuf, msqbuf32, msg_pad4[3]);
 1501                 error = copyout(&msqbuf32, uap->buf, sizeof(struct msqid_ds32));
 1502         }
 1503         return (error);
 1504 }
 1505 
 1506 int
 1507 freebsd32_msgsnd(struct thread *td, struct freebsd32_msgsnd_args *uap)
 1508 {
 1509         const void *msgp;
 1510         long mtype;
 1511         int32_t mtype32;
 1512         int error;
 1513 
 1514         msgp = PTRIN(uap->msgp);
 1515         if ((error = copyin(msgp, &mtype32, sizeof(mtype32))) != 0)
 1516                 return (error);
 1517         mtype = mtype32;
 1518         return (kern_msgsnd(td, uap->msqid,
 1519             (const char *)msgp + sizeof(mtype32),
 1520             uap->msgsz, uap->msgflg, mtype));
 1521 }
 1522 
 1523 int
 1524 freebsd32_msgrcv(struct thread *td, struct freebsd32_msgrcv_args *uap)
 1525 {
 1526         void *msgp;
 1527         long mtype;
 1528         int32_t mtype32;
 1529         int error;
 1530 
 1531         msgp = PTRIN(uap->msgp);
 1532         if ((error = kern_msgrcv(td, uap->msqid,
 1533             (char *)msgp + sizeof(mtype32), uap->msgsz,
 1534             uap->msgtyp, uap->msgflg, &mtype)) != 0)
 1535                 return (error);
 1536         mtype32 = (int32_t)mtype;
 1537         return (copyout(&mtype32, msgp, sizeof(mtype32)));
 1538 }
 1539 
 1540 int
 1541 freebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap)
 1542 {
 1543 
 1544         switch (uap->which) {
 1545         case 0: {       /* shmat */
 1546                 struct shmat_args ap;
 1547 
 1548                 ap.shmid = uap->a2;
 1549                 ap.shmaddr = PTRIN(uap->a3);
 1550                 ap.shmflg = uap->a4;
 1551                 return (sysent[SYS_shmat].sy_call(td, &ap));
 1552         }
 1553         case 2: {       /* shmdt */
 1554                 struct shmdt_args ap;
 1555 
 1556                 ap.shmaddr = PTRIN(uap->a2);
 1557                 return (sysent[SYS_shmdt].sy_call(td, &ap));
 1558         }
 1559         case 3: {       /* shmget */
 1560                 struct shmget_args ap;
 1561 
 1562                 ap.key = uap->a2;
 1563                 ap.size = uap->a3;
 1564                 ap.shmflg = uap->a4;
 1565                 return (sysent[SYS_shmget].sy_call(td, &ap));
 1566         }
 1567         case 4: {       /* shmctl */
 1568                 struct freebsd32_shmctl_args ap;
 1569 
 1570                 ap.shmid = uap->a2;
 1571                 ap.cmd = uap->a3;
 1572                 ap.buf = PTRIN(uap->a4);
 1573                 return (freebsd32_shmctl(td, &ap));
 1574         }
 1575         case 1:         /* oshmctl */
 1576         default:
 1577                 return (EINVAL);
 1578         }
 1579 }
 1580 
 1581 int
 1582 freebsd32_shmctl(struct thread *td, struct freebsd32_shmctl_args *uap)
 1583 {
 1584         int error = 0;
 1585         union {
 1586                 struct shmid_ds shmid_ds;
 1587                 struct shm_info shm_info;
 1588                 struct shminfo shminfo;
 1589         } u;
 1590         union {
 1591                 struct shmid_ds32 shmid_ds32;
 1592                 struct shm_info32 shm_info32;
 1593                 struct shminfo32 shminfo32;
 1594         } u32;
 1595         size_t sz;
 1596         
 1597         if (uap->cmd == IPC_SET) {
 1598                 if ((error = copyin(uap->buf, &u32.shmid_ds32,
 1599                     sizeof(u32.shmid_ds32))))
 1600                         goto done;
 1601                 freebsd32_ipcperm_in(&u32.shmid_ds32.shm_perm,
 1602                     &u.shmid_ds.shm_perm);
 1603                 CP(u32.shmid_ds32, u.shmid_ds, shm_segsz);
 1604                 CP(u32.shmid_ds32, u.shmid_ds, shm_lpid);
 1605                 CP(u32.shmid_ds32, u.shmid_ds, shm_cpid);
 1606                 CP(u32.shmid_ds32, u.shmid_ds, shm_nattch);
 1607                 CP(u32.shmid_ds32, u.shmid_ds, shm_atime);
 1608                 CP(u32.shmid_ds32, u.shmid_ds, shm_dtime);
 1609                 CP(u32.shmid_ds32, u.shmid_ds, shm_ctime);
 1610                 PTRIN_CP(u32.shmid_ds32, u.shmid_ds, shm_internal);
 1611         }
 1612         
 1613         error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz);
 1614         if (error)
 1615                 goto done;
 1616         
 1617         /* Cases in which we need to copyout */
 1618         switch (uap->cmd) {
 1619         case IPC_INFO:
 1620                 CP(u.shminfo, u32.shminfo32, shmmax);
 1621                 CP(u.shminfo, u32.shminfo32, shmmin);
 1622                 CP(u.shminfo, u32.shminfo32, shmmni);
 1623                 CP(u.shminfo, u32.shminfo32, shmseg);
 1624                 CP(u.shminfo, u32.shminfo32, shmall);
 1625                 error = copyout(&u32.shminfo32, uap->buf,
 1626                     sizeof(u32.shminfo32));
 1627                 break;
 1628         case SHM_INFO:
 1629                 CP(u.shm_info, u32.shm_info32, used_ids);
 1630                 CP(u.shm_info, u32.shm_info32, shm_rss);
 1631                 CP(u.shm_info, u32.shm_info32, shm_tot);
 1632                 CP(u.shm_info, u32.shm_info32, shm_swp);
 1633                 CP(u.shm_info, u32.shm_info32, swap_attempts);
 1634                 CP(u.shm_info, u32.shm_info32, swap_successes);
 1635                 error = copyout(&u32.shm_info32, uap->buf,
 1636                     sizeof(u32.shm_info32));
 1637                 break;
 1638         case SHM_STAT:
 1639         case IPC_STAT:
 1640                 freebsd32_ipcperm_out(&u.shmid_ds.shm_perm,
 1641                     &u32.shmid_ds32.shm_perm);
 1642                 CP(u.shmid_ds, u32.shmid_ds32, shm_segsz);
 1643                 CP(u.shmid_ds, u32.shmid_ds32, shm_lpid);
 1644                 CP(u.shmid_ds, u32.shmid_ds32, shm_cpid);
 1645                 CP(u.shmid_ds, u32.shmid_ds32, shm_nattch);
 1646                 CP(u.shmid_ds, u32.shmid_ds32, shm_atime);
 1647                 CP(u.shmid_ds, u32.shmid_ds32, shm_dtime);
 1648                 CP(u.shmid_ds, u32.shmid_ds32, shm_ctime);
 1649                 PTROUT_CP(u.shmid_ds, u32.shmid_ds32, shm_internal);
 1650                 error = copyout(&u32.shmid_ds32, uap->buf,
 1651                     sizeof(u32.shmid_ds32));
 1652                 break;
 1653         }
 1654 
 1655 done:
 1656         if (error) {
 1657                 /* Invalidate the return value */
 1658                 td->td_retval[0] = -1;
 1659         }
 1660         return (error);
 1661 }
 1662 
 1663 int
 1664 freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
 1665 {
 1666         struct pread_args ap;
 1667 
 1668         ap.fd = uap->fd;
 1669         ap.buf = uap->buf;
 1670         ap.nbyte = uap->nbyte;
 1671         ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
 1672         return (pread(td, &ap));
 1673 }
 1674 
 1675 int
 1676 freebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap)
 1677 {
 1678         struct pwrite_args ap;
 1679 
 1680         ap.fd = uap->fd;
 1681         ap.buf = uap->buf;
 1682         ap.nbyte = uap->nbyte;
 1683         ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
 1684         return (pwrite(td, &ap));
 1685 }
 1686 
 1687 int
 1688 freebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap)
 1689 {
 1690         int error;
 1691         struct lseek_args ap;
 1692         off_t pos;
 1693 
 1694         ap.fd = uap->fd;
 1695         ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
 1696         ap.whence = uap->whence;
 1697         error = lseek(td, &ap);
 1698         /* Expand the quad return into two parts for eax and edx */
 1699         pos = *(off_t *)(td->td_retval);
 1700         td->td_retval[0] = pos & 0xffffffff;    /* %eax */
 1701         td->td_retval[1] = pos >> 32;           /* %edx */
 1702         return error;
 1703 }
 1704 
 1705 int
 1706 freebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap)
 1707 {
 1708         struct truncate_args ap;
 1709 
 1710         ap.path = uap->path;
 1711         ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
 1712         return (truncate(td, &ap));
 1713 }
 1714 
 1715 int
 1716 freebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
 1717 {
 1718         struct ftruncate_args ap;
 1719 
 1720         ap.fd = uap->fd;
 1721         ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
 1722         return (ftruncate(td, &ap));
 1723 }
 1724 
 1725 #ifdef COMPAT_FREEBSD6
 1726 /* versions with the 'int pad' argument */
 1727 int
 1728 freebsd6_freebsd32_pread(struct thread *td, struct freebsd6_freebsd32_pread_args *uap)
 1729 {
 1730         struct pread_args ap;
 1731 
 1732         ap.fd = uap->fd;
 1733         ap.buf = uap->buf;
 1734         ap.nbyte = uap->nbyte;
 1735         ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
 1736         return (pread(td, &ap));
 1737 }
 1738 
 1739 int
 1740 freebsd6_freebsd32_pwrite(struct thread *td, struct freebsd6_freebsd32_pwrite_args *uap)
 1741 {
 1742         struct pwrite_args ap;
 1743 
 1744         ap.fd = uap->fd;
 1745         ap.buf = uap->buf;
 1746         ap.nbyte = uap->nbyte;
 1747         ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
 1748         return (pwrite(td, &ap));
 1749 }
 1750 
 1751 int
 1752 freebsd6_freebsd32_lseek(struct thread *td, struct freebsd6_freebsd32_lseek_args *uap)
 1753 {
 1754         int error;
 1755         struct lseek_args ap;
 1756         off_t pos;
 1757 
 1758         ap.fd = uap->fd;
 1759         ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
 1760         ap.whence = uap->whence;
 1761         error = lseek(td, &ap);
 1762         /* Expand the quad return into two parts for eax and edx */
 1763         pos = *(off_t *)(td->td_retval);
 1764         td->td_retval[0] = pos & 0xffffffff;    /* %eax */
 1765         td->td_retval[1] = pos >> 32;           /* %edx */
 1766         return error;
 1767 }
 1768 
 1769 int
 1770 freebsd6_freebsd32_truncate(struct thread *td, struct freebsd6_freebsd32_truncate_args *uap)
 1771 {
 1772         struct truncate_args ap;
 1773 
 1774         ap.path = uap->path;
 1775         ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
 1776         return (truncate(td, &ap));
 1777 }
 1778 
 1779 int
 1780 freebsd6_freebsd32_ftruncate(struct thread *td, struct freebsd6_freebsd32_ftruncate_args *uap)
 1781 {
 1782         struct ftruncate_args ap;
 1783 
 1784         ap.fd = uap->fd;
 1785         ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
 1786         return (ftruncate(td, &ap));
 1787 }
 1788 #endif /* COMPAT_FREEBSD6 */
 1789 
 1790 struct sf_hdtr32 {
 1791         uint32_t headers;
 1792         int hdr_cnt;
 1793         uint32_t trailers;
 1794         int trl_cnt;
 1795 };
 1796 
 1797 static int
 1798 freebsd32_do_sendfile(struct thread *td,
 1799     struct freebsd32_sendfile_args *uap, int compat)
 1800 {
 1801         struct sendfile_args ap;
 1802         struct sf_hdtr32 hdtr32;
 1803         struct sf_hdtr hdtr;
 1804         struct uio *hdr_uio, *trl_uio;
 1805         struct iovec32 *iov32;
 1806         int error;
 1807 
 1808         hdr_uio = trl_uio = NULL;
 1809 
 1810         ap.fd = uap->fd;
 1811         ap.s = uap->s;
 1812         ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
 1813         ap.nbytes = uap->nbytes;
 1814         ap.hdtr = (struct sf_hdtr *)uap->hdtr;          /* XXX not used */
 1815         ap.sbytes = uap->sbytes;
 1816         ap.flags = uap->flags;
 1817 
 1818         if (uap->hdtr != NULL) {
 1819                 error = copyin(uap->hdtr, &hdtr32, sizeof(hdtr32));
 1820                 if (error)
 1821                         goto out;
 1822                 PTRIN_CP(hdtr32, hdtr, headers);
 1823                 CP(hdtr32, hdtr, hdr_cnt);
 1824                 PTRIN_CP(hdtr32, hdtr, trailers);
 1825                 CP(hdtr32, hdtr, trl_cnt);
 1826 
 1827                 if (hdtr.headers != NULL) {
 1828                         iov32 = PTRIN(hdtr32.headers);
 1829                         error = freebsd32_copyinuio(iov32,
 1830                             hdtr32.hdr_cnt, &hdr_uio);
 1831                         if (error)
 1832                                 goto out;
 1833                 }
 1834                 if (hdtr.trailers != NULL) {
 1835                         iov32 = PTRIN(hdtr32.trailers);
 1836                         error = freebsd32_copyinuio(iov32,
 1837                             hdtr32.trl_cnt, &trl_uio);
 1838                         if (error)
 1839                                 goto out;
 1840                 }
 1841         }
 1842 
 1843         error = kern_sendfile(td, &ap, hdr_uio, trl_uio, compat);
 1844 out:
 1845         if (hdr_uio)
 1846                 free(hdr_uio, M_IOV);
 1847         if (trl_uio)
 1848                 free(trl_uio, M_IOV);
 1849         return (error);
 1850 }
 1851 
 1852 #ifdef COMPAT_FREEBSD4
 1853 int
 1854 freebsd4_freebsd32_sendfile(struct thread *td,
 1855     struct freebsd4_freebsd32_sendfile_args *uap)
 1856 {
 1857         return (freebsd32_do_sendfile(td,
 1858             (struct freebsd32_sendfile_args *)uap, 1));
 1859 }
 1860 #endif
 1861 
 1862 int
 1863 freebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap)
 1864 {
 1865 
 1866         return (freebsd32_do_sendfile(td, uap, 0));
 1867 }
 1868 
 1869 static void
 1870 copy_stat( struct stat *in, struct stat32 *out)
 1871 {
 1872         CP(*in, *out, st_dev);
 1873         CP(*in, *out, st_ino);
 1874         CP(*in, *out, st_mode);
 1875         CP(*in, *out, st_nlink);
 1876         CP(*in, *out, st_uid);
 1877         CP(*in, *out, st_gid);
 1878         CP(*in, *out, st_rdev);
 1879         TS_CP(*in, *out, st_atimespec);
 1880         TS_CP(*in, *out, st_mtimespec);
 1881         TS_CP(*in, *out, st_ctimespec);
 1882         CP(*in, *out, st_size);
 1883         CP(*in, *out, st_blocks);
 1884         CP(*in, *out, st_blksize);
 1885         CP(*in, *out, st_flags);
 1886         CP(*in, *out, st_gen);
 1887 }
 1888 
 1889 int
 1890 freebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap)
 1891 {
 1892         struct stat sb;
 1893         struct stat32 sb32;
 1894         int error;
 1895 
 1896         error = kern_stat(td, uap->path, UIO_USERSPACE, &sb);
 1897         if (error)
 1898                 return (error);
 1899         copy_stat(&sb, &sb32);
 1900         error = copyout(&sb32, uap->ub, sizeof (sb32));
 1901         return (error);
 1902 }
 1903 
 1904 int
 1905 freebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap)
 1906 {
 1907         struct stat ub;
 1908         struct stat32 ub32;
 1909         int error;
 1910 
 1911         error = kern_fstat(td, uap->fd, &ub);
 1912         if (error)
 1913                 return (error);
 1914         copy_stat(&ub, &ub32);
 1915         error = copyout(&ub32, uap->ub, sizeof(ub32));
 1916         return (error);
 1917 }
 1918 
 1919 int
 1920 freebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap)
 1921 {
 1922         struct stat sb;
 1923         struct stat32 sb32;
 1924         int error;
 1925 
 1926         error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb);
 1927         if (error)
 1928                 return (error);
 1929         copy_stat(&sb, &sb32);
 1930         error = copyout(&sb32, uap->ub, sizeof (sb32));
 1931         return (error);
 1932 }
 1933 
 1934 /*
 1935  * MPSAFE
 1936  */
 1937 int
 1938 freebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap)
 1939 {
 1940         int error, name[CTL_MAXNAME];
 1941         size_t j, oldlen;
 1942 
 1943         if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
 1944                 return (EINVAL);
 1945         error = copyin(uap->name, name, uap->namelen * sizeof(int));
 1946         if (error)
 1947                 return (error);
 1948         mtx_lock(&Giant);
 1949         if (uap->oldlenp)
 1950                 oldlen = fuword32(uap->oldlenp);
 1951         else
 1952                 oldlen = 0;
 1953         error = userland_sysctl(td, name, uap->namelen,
 1954                 uap->old, &oldlen, 1,
 1955                 uap->new, uap->newlen, &j, SCTL_MASK32);
 1956         if (error && error != ENOMEM)
 1957                 goto done2;
 1958         if (uap->oldlenp)
 1959                 suword32(uap->oldlenp, j);
 1960 done2:
 1961         mtx_unlock(&Giant);
 1962         return (error);
 1963 }
 1964 
 1965 int
 1966 freebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap)
 1967 {
 1968         struct sigaction32 s32;
 1969         struct sigaction sa, osa, *sap;
 1970         int error;
 1971 
 1972         if (uap->act) {
 1973                 error = copyin(uap->act, &s32, sizeof(s32));
 1974                 if (error)
 1975                         return (error);
 1976                 sa.sa_handler = PTRIN(s32.sa_u);
 1977                 CP(s32, sa, sa_flags);
 1978                 CP(s32, sa, sa_mask);
 1979                 sap = &sa;
 1980         } else
 1981                 sap = NULL;
 1982         error = kern_sigaction(td, uap->sig, sap, &osa, 0);
 1983         if (error == 0 && uap->oact != NULL) {
 1984                 s32.sa_u = PTROUT(osa.sa_handler);
 1985                 CP(osa, s32, sa_flags);
 1986                 CP(osa, s32, sa_mask);
 1987                 error = copyout(&s32, uap->oact, sizeof(s32));
 1988         }
 1989         return (error);
 1990 }
 1991 
 1992 #ifdef COMPAT_FREEBSD4
 1993 int
 1994 freebsd4_freebsd32_sigaction(struct thread *td,
 1995                              struct freebsd4_freebsd32_sigaction_args *uap)
 1996 {
 1997         struct sigaction32 s32;
 1998         struct sigaction sa, osa, *sap;
 1999         int error;
 2000 
 2001         if (uap->act) {
 2002                 error = copyin(uap->act, &s32, sizeof(s32));
 2003                 if (error)
 2004                         return (error);
 2005                 sa.sa_handler = PTRIN(s32.sa_u);
 2006                 CP(s32, sa, sa_flags);
 2007                 CP(s32, sa, sa_mask);
 2008                 sap = &sa;
 2009         } else
 2010                 sap = NULL;
 2011         error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4);
 2012         if (error == 0 && uap->oact != NULL) {
 2013                 s32.sa_u = PTROUT(osa.sa_handler);
 2014                 CP(osa, s32, sa_flags);
 2015                 CP(osa, s32, sa_mask);
 2016                 error = copyout(&s32, uap->oact, sizeof(s32));
 2017         }
 2018         return (error);
 2019 }
 2020 #endif
 2021 
 2022 #ifdef COMPAT_43
 2023 struct osigaction32 {
 2024         u_int32_t       sa_u;
 2025         osigset_t       sa_mask;
 2026         int             sa_flags;
 2027 };
 2028 
 2029 #define ONSIG   32
 2030 
 2031 int
 2032 ofreebsd32_sigaction(struct thread *td,
 2033                              struct ofreebsd32_sigaction_args *uap)
 2034 {
 2035         struct osigaction32 s32;
 2036         struct sigaction sa, osa, *sap;
 2037         int error;
 2038 
 2039         if (uap->signum <= 0 || uap->signum >= ONSIG)
 2040                 return (EINVAL);
 2041 
 2042         if (uap->nsa) {
 2043                 error = copyin(uap->nsa, &s32, sizeof(s32));
 2044                 if (error)
 2045                         return (error);
 2046                 sa.sa_handler = PTRIN(s32.sa_u);
 2047                 CP(s32, sa, sa_flags);
 2048                 OSIG2SIG(s32.sa_mask, sa.sa_mask);
 2049                 sap = &sa;
 2050         } else
 2051                 sap = NULL;
 2052         error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
 2053         if (error == 0 && uap->osa != NULL) {
 2054                 s32.sa_u = PTROUT(osa.sa_handler);
 2055                 CP(osa, s32, sa_flags);
 2056                 SIG2OSIG(osa.sa_mask, s32.sa_mask);
 2057                 error = copyout(&s32, uap->osa, sizeof(s32));
 2058         }
 2059         return (error);
 2060 }
 2061 
 2062 int
 2063 ofreebsd32_sigprocmask(struct thread *td,
 2064                                struct ofreebsd32_sigprocmask_args *uap)
 2065 {
 2066         sigset_t set, oset;
 2067         int error;
 2068 
 2069         OSIG2SIG(uap->mask, set);
 2070         error = kern_sigprocmask(td, uap->how, &set, &oset, 1);
 2071         SIG2OSIG(oset, td->td_retval[0]);
 2072         return (error);
 2073 }
 2074 
 2075 int
 2076 ofreebsd32_sigpending(struct thread *td,
 2077                               struct ofreebsd32_sigpending_args *uap)
 2078 {
 2079         struct proc *p = td->td_proc;
 2080         sigset_t siglist;
 2081 
 2082         PROC_LOCK(p);
 2083         siglist = p->p_siglist;
 2084         SIGSETOR(siglist, td->td_siglist);
 2085         PROC_UNLOCK(p);
 2086         SIG2OSIG(siglist, td->td_retval[0]);
 2087         return (0);
 2088 }
 2089 
 2090 struct sigvec32 {
 2091         u_int32_t       sv_handler;
 2092         int             sv_mask;
 2093         int             sv_flags;
 2094 };
 2095 
 2096 int
 2097 ofreebsd32_sigvec(struct thread *td,
 2098                           struct ofreebsd32_sigvec_args *uap)
 2099 {
 2100         struct sigvec32 vec;
 2101         struct sigaction sa, osa, *sap;
 2102         int error;
 2103 
 2104         if (uap->signum <= 0 || uap->signum >= ONSIG)
 2105                 return (EINVAL);
 2106 
 2107         if (uap->nsv) {
 2108                 error = copyin(uap->nsv, &vec, sizeof(vec));
 2109                 if (error)
 2110                         return (error);
 2111                 sa.sa_handler = PTRIN(vec.sv_handler);
 2112                 OSIG2SIG(vec.sv_mask, sa.sa_mask);
 2113                 sa.sa_flags = vec.sv_flags;
 2114                 sa.sa_flags ^= SA_RESTART;
 2115                 sap = &sa;
 2116         } else
 2117                 sap = NULL;
 2118         error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET);
 2119         if (error == 0 && uap->osv != NULL) {
 2120                 vec.sv_handler = PTROUT(osa.sa_handler);
 2121                 SIG2OSIG(osa.sa_mask, vec.sv_mask);
 2122                 vec.sv_flags = osa.sa_flags;
 2123                 vec.sv_flags &= ~SA_NOCLDWAIT;
 2124                 vec.sv_flags ^= SA_RESTART;
 2125                 error = copyout(&vec, uap->osv, sizeof(vec));
 2126         }
 2127         return (error);
 2128 }
 2129 
 2130 int
 2131 ofreebsd32_sigblock(struct thread *td,
 2132                             struct ofreebsd32_sigblock_args *uap)
 2133 {
 2134         struct proc *p = td->td_proc;
 2135         sigset_t set;
 2136 
 2137         OSIG2SIG(uap->mask, set);
 2138         SIG_CANTMASK(set);
 2139         PROC_LOCK(p);
 2140         SIG2OSIG(td->td_sigmask, td->td_retval[0]);
 2141         SIGSETOR(td->td_sigmask, set);
 2142         PROC_UNLOCK(p);
 2143         return (0);
 2144 }
 2145 
 2146 int
 2147 ofreebsd32_sigsetmask(struct thread *td,
 2148                               struct ofreebsd32_sigsetmask_args *uap)
 2149 {
 2150         struct proc *p = td->td_proc;
 2151         sigset_t set;
 2152 
 2153         OSIG2SIG(uap->mask, set);
 2154         SIG_CANTMASK(set);
 2155         PROC_LOCK(p);
 2156         SIG2OSIG(td->td_sigmask, td->td_retval[0]);
 2157         SIGSETLO(td->td_sigmask, set);
 2158         signotify(td);
 2159         PROC_UNLOCK(p);
 2160         return (0);
 2161 }
 2162 
 2163 int
 2164 ofreebsd32_sigsuspend(struct thread *td,
 2165                               struct ofreebsd32_sigsuspend_args *uap)
 2166 {
 2167         struct proc *p = td->td_proc;
 2168         sigset_t mask;
 2169 
 2170         PROC_LOCK(p);
 2171         td->td_oldsigmask = td->td_sigmask;
 2172         td->td_pflags |= TDP_OLDMASK;
 2173         OSIG2SIG(uap->mask, mask);
 2174         SIG_CANTMASK(mask);
 2175         SIGSETLO(td->td_sigmask, mask);
 2176         signotify(td);
 2177         while (msleep(&p->p_sigacts, &p->p_mtx, PPAUSE|PCATCH, "opause", 0) == 0)
 2178                 /* void */;
 2179         PROC_UNLOCK(p);
 2180         /* always return EINTR rather than ERESTART... */
 2181         return (EINTR);
 2182 }
 2183 
 2184 struct sigstack32 {
 2185         u_int32_t       ss_sp;
 2186         int             ss_onstack;
 2187 };
 2188 
 2189 int
 2190 ofreebsd32_sigstack(struct thread *td,
 2191                             struct ofreebsd32_sigstack_args *uap)
 2192 {
 2193         struct sigstack32 s32;
 2194         struct sigstack nss, oss;
 2195         int error = 0, unss;
 2196 
 2197         if (uap->nss != NULL) {
 2198                 error = copyin(uap->nss, &s32, sizeof(s32));
 2199                 if (error)
 2200                         return (error);
 2201                 nss.ss_sp = PTRIN(s32.ss_sp);
 2202                 CP(s32, nss, ss_onstack);
 2203                 unss = 1;
 2204         } else {
 2205                 unss = 0;
 2206         }
 2207         oss.ss_sp = td->td_sigstk.ss_sp;
 2208         oss.ss_onstack = sigonstack(cpu_getstack(td));
 2209         if (unss) {
 2210                 td->td_sigstk.ss_sp = nss.ss_sp;
 2211                 td->td_sigstk.ss_size = 0;
 2212                 td->td_sigstk.ss_flags |= (nss.ss_onstack & SS_ONSTACK);
 2213                 td->td_pflags |= TDP_ALTSTACK;
 2214         }
 2215         if (uap->oss != NULL) {
 2216                 s32.ss_sp = PTROUT(oss.ss_sp);
 2217                 CP(oss, s32, ss_onstack);
 2218                 error = copyout(&s32, uap->oss, sizeof(s32));
 2219         }
 2220         return (error);
 2221 }
 2222 #endif
 2223 
 2224 int
 2225 freebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap)
 2226 {
 2227         struct timespec32 rmt32, rqt32;
 2228         struct timespec rmt, rqt;
 2229         int error;
 2230 
 2231         error = copyin(uap->rqtp, &rqt32, sizeof(rqt32));
 2232         if (error)
 2233                 return (error);
 2234 
 2235         CP(rqt32, rqt, tv_sec);
 2236         CP(rqt32, rqt, tv_nsec);
 2237 
 2238         if (uap->rmtp &&
 2239             !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE))
 2240                 return (EFAULT);
 2241         error = kern_nanosleep(td, &rqt, &rmt);
 2242         if (error && uap->rmtp) {
 2243                 int error2;
 2244 
 2245                 CP(rmt, rmt32, tv_sec);
 2246                 CP(rmt, rmt32, tv_nsec);
 2247 
 2248                 error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt32));
 2249                 if (error2)
 2250                         error = error2;
 2251         }
 2252         return (error);
 2253 }
 2254 
 2255 int
 2256 freebsd32_clock_gettime(struct thread *td,
 2257                         struct freebsd32_clock_gettime_args *uap)
 2258 {
 2259         struct timespec ats;
 2260         struct timespec32 ats32;
 2261         int error;
 2262 
 2263         error = kern_clock_gettime(td, uap->clock_id, &ats);
 2264         if (error == 0) {
 2265                 CP(ats, ats32, tv_sec);
 2266                 CP(ats, ats32, tv_nsec);
 2267                 error = copyout(&ats32, uap->tp, sizeof(ats32));
 2268         }
 2269         return (error);
 2270 }
 2271 
 2272 int
 2273 freebsd32_clock_settime(struct thread *td,
 2274                         struct freebsd32_clock_settime_args *uap)
 2275 {
 2276         struct timespec ats;
 2277         struct timespec32 ats32;
 2278         int error;
 2279 
 2280         error = copyin(uap->tp, &ats32, sizeof(ats32));
 2281         if (error)
 2282                 return (error);
 2283         CP(ats32, ats, tv_sec);
 2284         CP(ats32, ats, tv_nsec);
 2285 
 2286         return (kern_clock_settime(td, uap->clock_id, &ats));
 2287 }
 2288 
 2289 int
 2290 freebsd32_clock_getres(struct thread *td,
 2291                        struct freebsd32_clock_getres_args *uap)
 2292 {
 2293         struct timespec ts;
 2294         struct timespec32 ts32;
 2295         int error;
 2296 
 2297         if (uap->tp == NULL)
 2298                 return (0);
 2299         error = kern_clock_getres(td, uap->clock_id, &ts);
 2300         if (error == 0) {
 2301                 CP(ts, ts32, tv_sec);
 2302                 CP(ts, ts32, tv_nsec);
 2303                 error = copyout(&ts32, uap->tp, sizeof(ts32));
 2304         }
 2305         return (error);
 2306 }
 2307 
 2308 int
 2309 freebsd32_thr_new(struct thread *td,
 2310                   struct freebsd32_thr_new_args *uap)
 2311 {
 2312         struct thr_param32 param32;
 2313         struct thr_param param;
 2314         int error;
 2315 
 2316         if (uap->param_size < 0 ||
 2317             uap->param_size > sizeof(struct thr_param32))
 2318                 return (EINVAL);
 2319         bzero(&param, sizeof(struct thr_param));
 2320         bzero(&param32, sizeof(struct thr_param32));
 2321         error = copyin(uap->param, &param32, uap->param_size);
 2322         if (error != 0)
 2323                 return (error);
 2324         param.start_func = PTRIN(param32.start_func);
 2325         param.arg = PTRIN(param32.arg);
 2326         param.stack_base = PTRIN(param32.stack_base);
 2327         param.stack_size = param32.stack_size;
 2328         param.tls_base = PTRIN(param32.tls_base);
 2329         param.tls_size = param32.tls_size;
 2330         param.child_tid = PTRIN(param32.child_tid);
 2331         param.parent_tid = PTRIN(param32.parent_tid);
 2332         param.flags = param32.flags;
 2333         param.rtp = PTRIN(param32.rtp);
 2334         param.spare[0] = PTRIN(param32.spare[0]);
 2335         param.spare[1] = PTRIN(param32.spare[1]);
 2336         param.spare[2] = PTRIN(param32.spare[2]);
 2337 
 2338         return (kern_thr_new(td, &param));
 2339 }
 2340 
 2341 int
 2342 freebsd32_thr_suspend(struct thread *td, struct freebsd32_thr_suspend_args *uap)
 2343 {
 2344         struct timespec32 ts32;
 2345         struct timespec ts, *tsp;
 2346         int error;
 2347 
 2348         error = 0;
 2349         tsp = NULL;
 2350         if (uap->timeout != NULL) {
 2351                 error = copyin((const void *)uap->timeout, (void *)&ts32,
 2352                     sizeof(struct timespec32));
 2353                 if (error != 0)
 2354                         return (error);
 2355                 ts.tv_sec = ts32.tv_sec;
 2356                 ts.tv_nsec = ts32.tv_nsec;
 2357                 tsp = &ts;
 2358         }
 2359         return (kern_thr_suspend(td, tsp));
 2360 }
 2361 
 2362 void
 2363 siginfo_to_siginfo32(siginfo_t *src, struct siginfo32 *dst)
 2364 {
 2365         bzero(dst, sizeof(*dst));
 2366         dst->si_signo = src->si_signo;
 2367         dst->si_errno = src->si_errno;
 2368         dst->si_code = src->si_code;
 2369         dst->si_pid = src->si_pid;
 2370         dst->si_uid = src->si_uid;
 2371         dst->si_status = src->si_status;
 2372         dst->si_addr = dst->si_addr;
 2373         dst->si_value.sigval_int = src->si_value.sival_int;
 2374         dst->si_timerid = src->si_timerid;
 2375         dst->si_overrun = src->si_overrun;
 2376 }
 2377 
 2378 int
 2379 freebsd32_sigtimedwait(struct thread *td, struct freebsd32_sigtimedwait_args *uap)
 2380 {
 2381         struct timespec32 ts32;
 2382         struct timespec ts;
 2383         struct timespec *timeout;
 2384         sigset_t set;
 2385         ksiginfo_t ksi;
 2386         struct siginfo32 si32;
 2387         int error;
 2388 
 2389         if (uap->timeout) {
 2390                 error = copyin(uap->timeout, &ts32, sizeof(ts32));
 2391                 if (error)
 2392                         return (error);
 2393                 ts.tv_sec = ts32.tv_sec;
 2394                 ts.tv_nsec = ts32.tv_nsec;
 2395                 timeout = &ts;
 2396         } else
 2397                 timeout = NULL;
 2398 
 2399         error = copyin(uap->set, &set, sizeof(set));
 2400         if (error)
 2401                 return (error);
 2402 
 2403         error = kern_sigtimedwait(td, set, &ksi, timeout);
 2404         if (error)
 2405                 return (error);
 2406 
 2407         if (uap->info) {
 2408                 siginfo_to_siginfo32(&ksi.ksi_info, &si32);
 2409                 error = copyout(&si32, uap->info, sizeof(struct siginfo32));
 2410         }
 2411 
 2412         if (error == 0)
 2413                 td->td_retval[0] = ksi.ksi_signo;
 2414         return (error);
 2415 }
 2416 
 2417 /*
 2418  * MPSAFE
 2419  */
 2420 int
 2421 freebsd32_sigwaitinfo(struct thread *td, struct freebsd32_sigwaitinfo_args *uap)
 2422 {
 2423         ksiginfo_t ksi;
 2424         struct siginfo32 si32;
 2425         sigset_t set;
 2426         int error;
 2427 
 2428         error = copyin(uap->set, &set, sizeof(set));
 2429         if (error)
 2430                 return (error);
 2431 
 2432         error = kern_sigtimedwait(td, set, &ksi, NULL);
 2433         if (error)
 2434                 return (error);
 2435 
 2436         if (uap->info) {
 2437                 siginfo_to_siginfo32(&ksi.ksi_info, &si32);
 2438                 error = copyout(&si32, uap->info, sizeof(struct siginfo32));
 2439         }       
 2440         if (error == 0)
 2441                 td->td_retval[0] = ksi.ksi_signo;
 2442         return (error);
 2443 }
 2444 
 2445 #if 0
 2446 
 2447 int
 2448 freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)
 2449 {
 2450         int error;
 2451         struct yyy32 *p32, s32;
 2452         struct yyy *p = NULL, s;
 2453 
 2454         if (uap->zzz) {
 2455                 error = copyin(uap->zzz, &s32, sizeof(s32));
 2456                 if (error)
 2457                         return (error);
 2458                 /* translate in */
 2459                 p = &s;
 2460         }
 2461         error = kern_xxx(td, p);
 2462         if (error)
 2463                 return (error);
 2464         if (uap->zzz) {
 2465                 /* translate out */
 2466                 error = copyout(&s32, p32, sizeof(s32));
 2467         }
 2468         return (error);
 2469 }
 2470 
 2471 #endif

Cache object: 2deade844708a6d3010a2e75ab9fec36


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