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

Cache object: d6ec74c020439dc85f48b8df2ffa9fec


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