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: releng/5.4/sys/compat/freebsd32/freebsd32_misc.c 142895 2005-03-01 09:30:19Z obrien $");
   29 
   30 #include "opt_compat.h"
   31 
   32 #include <sys/param.h>
   33 #include <sys/systm.h>
   34 #include <sys/bus.h>
   35 #include <sys/exec.h>
   36 #include <sys/fcntl.h>
   37 #include <sys/filedesc.h>
   38 #include <sys/namei.h>
   39 #include <sys/imgact.h>
   40 #include <sys/kernel.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/mman.h>
   45 #include <sys/module.h>
   46 #include <sys/mount.h>
   47 #include <sys/mutex.h>
   48 #include <sys/namei.h>
   49 #include <sys/param.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/pipe.h>           /* Must come after sys/selinfo.h */
   56 #include <sys/signal.h>
   57 #include <sys/signalvar.h>
   58 #include <sys/socket.h>
   59 #include <sys/socketvar.h>
   60 #include <sys/stat.h>
   61 #include <sys/syscallsubr.h>
   62 #include <sys/sysctl.h>
   63 #include <sys/sysent.h>
   64 #include <sys/sysproto.h>
   65 #include <sys/systm.h>
   66 #include <sys/unistd.h>
   67 #include <sys/vnode.h>
   68 #include <sys/wait.h>
   69 
   70 #include <vm/vm.h>
   71 #include <vm/vm_kern.h>
   72 #include <vm/vm_param.h>
   73 #include <vm/pmap.h>
   74 #include <vm/vm_map.h>
   75 #include <vm/vm_object.h>
   76 #include <vm/vm_extern.h>
   77 
   78 #include <compat/freebsd32/freebsd32_util.h>
   79 #include <compat/freebsd32/freebsd32.h>
   80 #include <compat/freebsd32/freebsd32_proto.h>
   81 
   82 CTASSERT(sizeof(struct timeval32) == 8);
   83 CTASSERT(sizeof(struct timespec32) == 8);
   84 CTASSERT(sizeof(struct statfs32) == 256);
   85 CTASSERT(sizeof(struct rusage32) == 72);
   86 
   87 int
   88 freebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap)
   89 {
   90         int error, status;
   91         struct rusage32 ru32;
   92         struct rusage ru;
   93 
   94         error = kern_wait(td, uap->pid, &status, uap->options, &ru);
   95         if (error)
   96                 return (error);
   97         if (uap->status != NULL)
   98                 error = copyout(&status, uap->status, sizeof(status));
   99         if (uap->rusage != NULL && error == 0) {
  100                 TV_CP(ru, ru32, ru_utime);
  101                 TV_CP(ru, ru32, ru_stime);
  102                 CP(ru, ru32, ru_maxrss);
  103                 CP(ru, ru32, ru_ixrss);
  104                 CP(ru, ru32, ru_idrss);
  105                 CP(ru, ru32, ru_isrss);
  106                 CP(ru, ru32, ru_minflt);
  107                 CP(ru, ru32, ru_majflt);
  108                 CP(ru, ru32, ru_nswap);
  109                 CP(ru, ru32, ru_inblock);
  110                 CP(ru, ru32, ru_oublock);
  111                 CP(ru, ru32, ru_msgsnd);
  112                 CP(ru, ru32, ru_msgrcv);
  113                 CP(ru, ru32, ru_nsignals);
  114                 CP(ru, ru32, ru_nvcsw);
  115                 CP(ru, ru32, ru_nivcsw);
  116                 error = copyout(&ru32, uap->rusage, sizeof(ru32));
  117         }
  118         return (error);
  119 }
  120 
  121 #ifdef COMPAT_FREEBSD4
  122 static void
  123 copy_statfs(struct statfs *in, struct statfs32 *out)
  124 {
  125         CP(*in, *out, f_bsize);
  126         CP(*in, *out, f_iosize);
  127         CP(*in, *out, f_blocks);
  128         CP(*in, *out, f_bfree);
  129         CP(*in, *out, f_bavail);
  130         CP(*in, *out, f_files);
  131         CP(*in, *out, f_ffree);
  132         CP(*in, *out, f_fsid);
  133         CP(*in, *out, f_owner);
  134         CP(*in, *out, f_type);
  135         CP(*in, *out, f_flags);
  136         CP(*in, *out, f_flags);
  137         CP(*in, *out, f_syncwrites);
  138         CP(*in, *out, f_asyncwrites);
  139         bcopy(in->f_fstypename,
  140               out->f_fstypename, MFSNAMELEN);
  141         bcopy(in->f_mntonname,
  142               out->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN));
  143         CP(*in, *out, f_syncreads);
  144         CP(*in, *out, f_asyncreads);
  145         bcopy(in->f_mntfromname,
  146               out->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN));
  147 }
  148 #endif
  149 
  150 #ifdef COMPAT_FREEBSD4
  151 int
  152 freebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap)
  153 {
  154         int error;
  155         caddr_t sg;
  156         struct statfs32 *sp32, stat32;
  157         struct statfs *sp = NULL, stat;
  158         int maxcount, count, i;
  159 
  160         sp32 = uap->buf;
  161         maxcount = uap->bufsize / sizeof(struct statfs32);
  162 
  163         if (sp32) {
  164                 sg = stackgap_init();
  165                 sp = stackgap_alloc(&sg, sizeof(struct statfs) * maxcount);
  166                 uap->buf = (struct statfs32 *)sp;
  167         }
  168         error = getfsstat(td, (struct getfsstat_args *) uap);
  169         if (sp32 && !error) {
  170                 count = td->td_retval[0];
  171                 for (i = 0; i < count; i++) {
  172                         error = copyin(&sp[i], &stat, sizeof(stat));
  173                         if (error)
  174                                 return (error);
  175                         copy_statfs(&stat, &stat32);
  176                         error = copyout(&stat32, &sp32[i], sizeof(stat32));
  177                         if (error)
  178                                 return (error);
  179                 }
  180         }
  181         return (error);
  182 }
  183 #endif
  184 
  185 struct sigaltstack32 {
  186         u_int32_t       ss_sp;
  187         u_int32_t       ss_size;
  188         int             ss_flags;
  189 };
  190 
  191 CTASSERT(sizeof(struct sigaltstack32) == 12);
  192 
  193 int
  194 freebsd32_sigaltstack(struct thread *td,
  195                       struct freebsd32_sigaltstack_args *uap)
  196 {
  197         struct sigaltstack32 s32;
  198         struct sigaltstack ss, oss, *ssp;
  199         int error;
  200 
  201         if (uap->ss != NULL) {
  202                 error = copyin(uap->ss, &s32, sizeof(s32));
  203                 if (error)
  204                         return (error);
  205                 PTRIN_CP(s32, ss, ss_sp);
  206                 CP(s32, ss, ss_size);
  207                 CP(s32, ss, ss_flags);
  208                 ssp = &ss;
  209         } else
  210                 ssp = NULL;
  211         error = kern_sigaltstack(td, ssp, &oss);
  212         if (error == 0 && uap->oss != NULL) {
  213                 PTROUT_CP(oss, s32, ss_sp);
  214                 CP(oss, s32, ss_size);
  215                 CP(oss, s32, ss_flags);
  216                 error = copyout(&s32, uap->oss, sizeof(s32));
  217         }
  218         return (error);
  219 }
  220 
  221 int
  222 freebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap)
  223 {
  224         int error;
  225         caddr_t sg;
  226         struct execve_args ap;
  227         u_int32_t *p32, arg;
  228         char **p, *p64;
  229         int count;
  230 
  231         sg = stackgap_init();
  232         ap.fname = uap->fname;
  233 
  234         if (uap->argv) {
  235                 count = 0;
  236                 p32 = uap->argv;
  237                 do {
  238                         error = copyin(p32++, &arg, sizeof(arg));
  239                         if (error)
  240                                 return error;
  241                         count++;
  242                 } while (arg != 0);
  243                 p = stackgap_alloc(&sg, count * sizeof(char *));
  244                 ap.argv = p;
  245                 p32 = uap->argv;
  246                 do {
  247                         error = copyin(p32++, &arg, sizeof(arg));
  248                         if (error)
  249                                 return error;
  250                         p64 = PTRIN(arg);
  251                         error = copyout(&p64, p++, sizeof(p64));
  252                         if (error)
  253                                 return error;
  254                 } while (arg != 0);
  255         }
  256         if (uap->envv) {
  257                 count = 0;
  258                 p32 = uap->envv;
  259                 do {
  260                         error = copyin(p32++, &arg, sizeof(arg));
  261                         if (error)
  262                                 return error;
  263                         count++;
  264                 } while (arg != 0);
  265                 p = stackgap_alloc(&sg, count * sizeof(char *));
  266                 ap.envv = p;
  267                 p32 = uap->envv;
  268                 do {
  269                         error = copyin(p32++, &arg, sizeof(arg));
  270                         if (error)
  271                                 return error;
  272                         p64 = PTRIN(arg);
  273                         error = copyout(&p64, p++, sizeof(p64));
  274                         if (error)
  275                                 return error;
  276                 } while (arg != 0);
  277         }
  278 
  279         return execve(td, &ap);
  280 }
  281 
  282 #ifdef __ia64__
  283 static int
  284 freebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end,
  285                        int prot, int fd, off_t pos)
  286 {
  287         vm_map_t map;
  288         vm_map_entry_t entry;
  289         int rv;
  290 
  291         map = &td->td_proc->p_vmspace->vm_map;
  292         if (fd != -1)
  293                 prot |= VM_PROT_WRITE;
  294 
  295         if (vm_map_lookup_entry(map, start, &entry)) {
  296                 if ((entry->protection & prot) != prot) {
  297                         rv = vm_map_protect(map,
  298                                             trunc_page(start),
  299                                             round_page(end),
  300                                             entry->protection | prot,
  301                                             FALSE);
  302                         if (rv != KERN_SUCCESS)
  303                                 return (EINVAL);
  304                 }
  305         } else {
  306                 vm_offset_t addr = trunc_page(start);
  307                 rv = vm_map_find(map, 0, 0,
  308                                  &addr, PAGE_SIZE, FALSE, prot,
  309                                  VM_PROT_ALL, 0);
  310                 if (rv != KERN_SUCCESS)
  311                         return (EINVAL);
  312         }
  313 
  314         if (fd != -1) {
  315                 struct pread_args r;
  316                 r.fd = fd;
  317                 r.buf = (void *) start;
  318                 r.nbyte = end - start;
  319                 r.offset = pos;
  320                 return (pread(td, &r));
  321         } else {
  322                 while (start < end) {
  323                         subyte((void *) start, 0);
  324                         start++;
  325                 }
  326                 return (0);
  327         }
  328 }
  329 #endif
  330 
  331 int
  332 freebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap)
  333 {
  334         struct mmap_args ap;
  335         vm_offset_t addr = (vm_offset_t) uap->addr;
  336         vm_size_t len    = uap->len;
  337         int prot         = uap->prot;
  338         int flags        = uap->flags;
  339         int fd           = uap->fd;
  340         off_t pos        = (uap->poslo
  341                             | ((off_t)uap->poshi << 32));
  342 #ifdef __ia64__
  343         vm_size_t pageoff;
  344         int error;
  345 
  346         /*
  347          * Attempt to handle page size hassles.
  348          */
  349         pageoff = (pos & PAGE_MASK);
  350         if (flags & MAP_FIXED) {
  351                 vm_offset_t start, end;
  352                 start = addr;
  353                 end = addr + len;
  354 
  355                 if (start != trunc_page(start)) {
  356                         error = freebsd32_mmap_partial(td, start,
  357                                                        round_page(start), prot,
  358                                                        fd, pos);
  359                         if (fd != -1)
  360                                 pos += round_page(start) - start;
  361                         start = round_page(start);
  362                 }
  363                 if (end != round_page(end)) {
  364                         vm_offset_t t = trunc_page(end);
  365                         error = freebsd32_mmap_partial(td, t, end,
  366                                                   prot, fd,
  367                                                   pos + t - start);
  368                         end = trunc_page(end);
  369                 }
  370                 if (end > start && fd != -1 && (pos & PAGE_MASK)) {
  371                         /*
  372                          * We can't map this region at all. The specified
  373                          * address doesn't have the same alignment as the file
  374                          * position. Fake the mapping by simply reading the
  375                          * entire region into memory. First we need to make
  376                          * sure the region exists.
  377                          */
  378                         vm_map_t map;
  379                         struct pread_args r;
  380                         int rv;
  381 
  382                         prot |= VM_PROT_WRITE;
  383                         map = &td->td_proc->p_vmspace->vm_map;
  384                         rv = vm_map_remove(map, start, end);
  385                         if (rv != KERN_SUCCESS)
  386                                 return (EINVAL);
  387                         rv = vm_map_find(map, 0, 0,
  388                                          &start, end - start, FALSE,
  389                                          prot, VM_PROT_ALL, 0);
  390                         if (rv != KERN_SUCCESS)
  391                                 return (EINVAL);
  392                         r.fd = fd;
  393                         r.buf = (void *) start;
  394                         r.nbyte = end - start;
  395                         r.offset = pos;
  396                         error = pread(td, &r);
  397                         if (error)
  398                                 return (error);
  399 
  400                         td->td_retval[0] = addr;
  401                         return (0);
  402                 }
  403                 if (end == start) {
  404                         /*
  405                          * After dealing with the ragged ends, there
  406                          * might be none left.
  407                          */
  408                         td->td_retval[0] = addr;
  409                         return (0);
  410                 }
  411                 addr = start;
  412                 len = end - start;
  413         }
  414 #endif
  415 
  416         ap.addr = (void *) addr;
  417         ap.len = len;
  418         ap.prot = prot;
  419         ap.flags = flags;
  420         ap.fd = fd;
  421         ap.pos = pos;
  422 
  423         return (mmap(td, &ap));
  424 }
  425 
  426 struct itimerval32 {
  427         struct timeval32 it_interval;
  428         struct timeval32 it_value;
  429 };
  430 
  431 CTASSERT(sizeof(struct itimerval32) == 16);
  432 
  433 int
  434 freebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap)
  435 {
  436         int error;
  437         caddr_t sg;
  438         struct itimerval32 *p32, *op32, s32;
  439         struct itimerval *p = NULL, *op = NULL, s;
  440 
  441         p32 = uap->itv;
  442         if (p32) {
  443                 sg = stackgap_init();
  444                 p = stackgap_alloc(&sg, sizeof(struct itimerval));
  445                 uap->itv = (struct itimerval32 *)p;
  446                 error = copyin(p32, &s32, sizeof(s32));
  447                 if (error)
  448                         return (error);
  449                 TV_CP(s32, s, it_interval);
  450                 TV_CP(s32, s, it_value);
  451                 error = copyout(&s, p, sizeof(s));
  452                 if (error)
  453                         return (error);
  454         }
  455         op32 = uap->oitv;
  456         if (op32) {
  457                 sg = stackgap_init();
  458                 op = stackgap_alloc(&sg, sizeof(struct itimerval));
  459                 uap->oitv = (struct itimerval32 *)op;
  460         }
  461         error = setitimer(td, (struct setitimer_args *) uap);
  462         if (error)
  463                 return (error);
  464         if (op32) {
  465                 error = copyin(op, &s, sizeof(s));
  466                 if (error)
  467                         return (error);
  468                 TV_CP(s, s32, it_interval);
  469                 TV_CP(s, s32, it_value);
  470                 error = copyout(&s32, op32, sizeof(s32));
  471         }
  472         return (error);
  473 }
  474 
  475 int
  476 freebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap)
  477 {
  478         int error;
  479         caddr_t sg;
  480         struct itimerval32 *p32, s32;
  481         struct itimerval *p = NULL, s;
  482 
  483         p32 = uap->itv;
  484         if (p32) {
  485                 sg = stackgap_init();
  486                 p = stackgap_alloc(&sg, sizeof(struct itimerval));
  487                 uap->itv = (struct itimerval32 *)p;
  488         }
  489         error = getitimer(td, (struct getitimer_args *) uap);
  490         if (error)
  491                 return (error);
  492         if (p32) {
  493                 error = copyin(p, &s, sizeof(s));
  494                 if (error)
  495                         return (error);
  496                 TV_CP(s, s32, it_interval);
  497                 TV_CP(s, s32, it_value);
  498                 error = copyout(&s32, p32, sizeof(s32));
  499         }
  500         return (error);
  501 }
  502 
  503 int
  504 freebsd32_select(struct thread *td, struct freebsd32_select_args *uap)
  505 {
  506         int error;
  507         caddr_t sg;
  508         struct timeval32 *p32, s32;
  509         struct timeval *p = NULL, s;
  510 
  511         p32 = uap->tv;
  512         if (p32) {
  513                 sg = stackgap_init();
  514                 p = stackgap_alloc(&sg, sizeof(struct timeval));
  515                 uap->tv = (struct timeval32 *)p;
  516                 error = copyin(p32, &s32, sizeof(s32));
  517                 if (error)
  518                         return (error);
  519                 CP(s32, s, tv_sec);
  520                 CP(s32, s, tv_usec);
  521                 error = copyout(&s, p, sizeof(s));
  522                 if (error)
  523                         return (error);
  524         }
  525         /*
  526          * XXX big-endian needs to convert the fd_sets too.
  527          */
  528         return (select(td, (struct select_args *) uap));
  529 }
  530 
  531 struct kevent32 {
  532         u_int32_t       ident;          /* identifier for this event */
  533         short           filter;         /* filter for event */
  534         u_short         flags;
  535         u_int           fflags;
  536         int32_t         data;
  537         u_int32_t       udata;          /* opaque user data identifier */
  538 };
  539 
  540 CTASSERT(sizeof(struct kevent32) == 20);
  541 
  542 int
  543 freebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap)
  544 {
  545         int error;
  546         caddr_t sg;
  547         struct timespec32 ts32;
  548         struct timespec ts;
  549         struct kevent32 ks32;
  550         struct kevent *ks;
  551         struct kevent_args a;
  552         int i;
  553 
  554         sg = stackgap_init();
  555 
  556         a.fd = uap->fd;
  557         a.changelist = uap->changelist;
  558         a.nchanges = uap->nchanges;
  559         a.eventlist = uap->eventlist;
  560         a.nevents = uap->nevents;
  561         a.timeout = NULL;
  562 
  563         if (uap->timeout) {
  564                 a.timeout = stackgap_alloc(&sg, sizeof(struct timespec));
  565                 error = copyin(uap->timeout, &ts32, sizeof(ts32));
  566                 if (error)
  567                         return (error);
  568                 CP(ts32, ts, tv_sec);
  569                 CP(ts32, ts, tv_nsec);
  570                 error = copyout(&ts, (void *)(uintptr_t)a.timeout, sizeof(ts));
  571                 if (error)
  572                         return (error);
  573         }
  574         if (uap->changelist) {
  575                 a.changelist = (struct kevent *)stackgap_alloc(&sg,
  576                     uap->nchanges * sizeof(struct kevent));
  577                 for (i = 0; i < uap->nchanges; i++) {
  578                         error = copyin(&uap->changelist[i], &ks32,
  579                             sizeof(ks32));
  580                         if (error)
  581                                 return (error);
  582                         ks = (struct kevent *)(uintptr_t)&a.changelist[i];
  583                         CP(ks32, *ks, ident);
  584                         CP(ks32, *ks, filter);
  585                         CP(ks32, *ks, flags);
  586                         CP(ks32, *ks, fflags);
  587                         CP(ks32, *ks, data);
  588                         PTRIN_CP(ks32, *ks, udata);
  589                 }
  590         }
  591         if (uap->eventlist) {
  592                 a.eventlist = stackgap_alloc(&sg,
  593                     uap->nevents * sizeof(struct kevent));
  594         }
  595         error = kevent(td, &a);
  596         if (uap->eventlist && error > 0) {
  597                 for (i = 0; i < error; i++) {
  598                         ks = &a.eventlist[i];
  599                         CP(*ks, ks32, ident);
  600                         CP(*ks, ks32, filter);
  601                         CP(*ks, ks32, flags);
  602                         CP(*ks, ks32, fflags);
  603                         CP(*ks, ks32, data);
  604                         PTROUT_CP(*ks, ks32, udata);
  605                         error = copyout(&ks32, &uap->eventlist[i],
  606                             sizeof(ks32));
  607                         if (error)
  608                                 return (error);
  609                 }
  610         }
  611         return error;
  612 }
  613 
  614 int
  615 freebsd32_gettimeofday(struct thread *td,
  616                        struct freebsd32_gettimeofday_args *uap)
  617 {
  618         struct timeval atv;
  619         struct timeval32 atv32;
  620         struct timezone rtz;
  621         int error = 0;
  622 
  623         if (uap->tp) {
  624                 microtime(&atv);
  625                 CP(atv, atv32, tv_sec);
  626                 CP(atv, atv32, tv_usec);
  627                 error = copyout(&atv32, uap->tp, sizeof (atv32));
  628         }
  629         if (error == 0 && uap->tzp != NULL) {
  630                 rtz.tz_minuteswest = tz_minuteswest;
  631                 rtz.tz_dsttime = tz_dsttime;
  632                 error = copyout(&rtz, uap->tzp, sizeof (rtz));
  633         }
  634         return (error);
  635 }
  636 
  637 int
  638 freebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap)
  639 {
  640         int error;
  641         caddr_t sg;
  642         struct rusage32 *p32, s32;
  643         struct rusage *p = NULL, s;
  644 
  645         p32 = uap->rusage;
  646         if (p32) {
  647                 sg = stackgap_init();
  648                 p = stackgap_alloc(&sg, sizeof(struct rusage));
  649                 uap->rusage = (struct rusage32 *)p;
  650         }
  651         error = getrusage(td, (struct getrusage_args *) uap);
  652         if (error)
  653                 return (error);
  654         if (p32) {
  655                 error = copyin(p, &s, sizeof(s));
  656                 if (error)
  657                         return (error);
  658                 TV_CP(s, s32, ru_utime);
  659                 TV_CP(s, s32, ru_stime);
  660                 CP(s, s32, ru_maxrss);
  661                 CP(s, s32, ru_ixrss);
  662                 CP(s, s32, ru_idrss);
  663                 CP(s, s32, ru_isrss);
  664                 CP(s, s32, ru_minflt);
  665                 CP(s, s32, ru_majflt);
  666                 CP(s, s32, ru_nswap);
  667                 CP(s, s32, ru_inblock);
  668                 CP(s, s32, ru_oublock);
  669                 CP(s, s32, ru_msgsnd);
  670                 CP(s, s32, ru_msgrcv);
  671                 CP(s, s32, ru_nsignals);
  672                 CP(s, s32, ru_nvcsw);
  673                 CP(s, s32, ru_nivcsw);
  674                 error = copyout(&s32, p32, sizeof(s32));
  675         }
  676         return (error);
  677 }
  678 
  679 struct iovec32 {
  680         u_int32_t iov_base;
  681         int     iov_len;
  682 };
  683 #define STACKGAPLEN     400
  684 
  685 CTASSERT(sizeof(struct iovec32) == 8);
  686 
  687 int
  688 freebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap)
  689 {
  690         int error, osize, nsize, i;
  691         caddr_t sg;
  692         struct readv_args /* {
  693                 syscallarg(int) fd;
  694                 syscallarg(struct iovec *) iovp;
  695                 syscallarg(u_int) iovcnt;
  696         } */ a;
  697         struct iovec32 *oio;
  698         struct iovec *nio;
  699 
  700         sg = stackgap_init();
  701 
  702         if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec)))
  703                 return (EINVAL);
  704 
  705         osize = uap->iovcnt * sizeof (struct iovec32);
  706         nsize = uap->iovcnt * sizeof (struct iovec);
  707 
  708         oio = malloc(osize, M_TEMP, M_WAITOK);
  709         nio = malloc(nsize, M_TEMP, M_WAITOK);
  710 
  711         error = 0;
  712         if ((error = copyin(uap->iovp, oio, osize)))
  713                 goto punt;
  714         for (i = 0; i < uap->iovcnt; i++) {
  715                 nio[i].iov_base = PTRIN(oio[i].iov_base);
  716                 nio[i].iov_len = oio[i].iov_len;
  717         }
  718 
  719         a.fd = uap->fd;
  720         a.iovp = stackgap_alloc(&sg, nsize);
  721         a.iovcnt = uap->iovcnt;
  722 
  723         if ((error = copyout(nio, (caddr_t)a.iovp, nsize)))
  724                 goto punt;
  725         error = readv(td, &a);
  726 
  727 punt:
  728         free(oio, M_TEMP);
  729         free(nio, M_TEMP);
  730         return (error);
  731 }
  732 
  733 int
  734 freebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap)
  735 {
  736         int error, i, nsize, osize;
  737         caddr_t sg;
  738         struct writev_args /* {
  739                 syscallarg(int) fd;
  740                 syscallarg(struct iovec *) iovp;
  741                 syscallarg(u_int) iovcnt;
  742         } */ a;
  743         struct iovec32 *oio;
  744         struct iovec *nio;
  745 
  746         sg = stackgap_init();
  747 
  748         if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec)))
  749                 return (EINVAL);
  750 
  751         osize = uap->iovcnt * sizeof (struct iovec32);
  752         nsize = uap->iovcnt * sizeof (struct iovec);
  753 
  754         oio = malloc(osize, M_TEMP, M_WAITOK);
  755         nio = malloc(nsize, M_TEMP, M_WAITOK);
  756 
  757         error = 0;
  758         if ((error = copyin(uap->iovp, oio, osize)))
  759                 goto punt;
  760         for (i = 0; i < uap->iovcnt; i++) {
  761                 nio[i].iov_base = PTRIN(oio[i].iov_base);
  762                 nio[i].iov_len = oio[i].iov_len;
  763         }
  764 
  765         a.fd = uap->fd;
  766         a.iovp = stackgap_alloc(&sg, nsize);
  767         a.iovcnt = uap->iovcnt;
  768 
  769         if ((error = copyout(nio, (caddr_t)a.iovp, nsize)))
  770                 goto punt;
  771         error = writev(td, &a);
  772 
  773 punt:
  774         free(oio, M_TEMP);
  775         free(nio, M_TEMP);
  776         return (error);
  777 }
  778 
  779 int
  780 freebsd32_settimeofday(struct thread *td,
  781                        struct freebsd32_settimeofday_args *uap)
  782 {
  783         int error;
  784         caddr_t sg;
  785         struct timeval32 *p32, s32;
  786         struct timeval *p = NULL, s;
  787 
  788         p32 = uap->tv;
  789         if (p32) {
  790                 sg = stackgap_init();
  791                 p = stackgap_alloc(&sg, sizeof(struct timeval));
  792                 uap->tv = (struct timeval32 *)p;
  793                 error = copyin(p32, &s32, sizeof(s32));
  794                 if (error)
  795                         return (error);
  796                 CP(s32, s, tv_sec);
  797                 CP(s32, s, tv_usec);
  798                 error = copyout(&s, p, sizeof(s));
  799                 if (error)
  800                         return (error);
  801         }
  802         return (settimeofday(td, (struct settimeofday_args *) uap));
  803 }
  804 
  805 int
  806 freebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap)
  807 {
  808         int error;
  809         caddr_t sg;
  810         struct timeval32 *p32, s32[2];
  811         struct timeval *p = NULL, s[2];
  812 
  813         p32 = uap->tptr;
  814         if (p32) {
  815                 sg = stackgap_init();
  816                 p = stackgap_alloc(&sg, 2*sizeof(struct timeval));
  817                 uap->tptr = (struct timeval32 *)p;
  818                 error = copyin(p32, s32, sizeof(s32));
  819                 if (error)
  820                         return (error);
  821                 CP(s32[0], s[0], tv_sec);
  822                 CP(s32[0], s[0], tv_usec);
  823                 CP(s32[1], s[1], tv_sec);
  824                 CP(s32[1], s[1], tv_usec);
  825                 error = copyout(s, p, sizeof(s));
  826                 if (error)
  827                         return (error);
  828         }
  829         return (utimes(td, (struct utimes_args *) uap));
  830 }
  831 
  832 int
  833 freebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap)
  834 {
  835         int error;
  836         caddr_t sg;
  837         struct timeval32 *p32, *op32, s32;
  838         struct timeval *p = NULL, *op = NULL, s;
  839 
  840         p32 = uap->delta;
  841         if (p32) {
  842                 sg = stackgap_init();
  843                 p = stackgap_alloc(&sg, sizeof(struct timeval));
  844                 uap->delta = (struct timeval32 *)p;
  845                 error = copyin(p32, &s32, sizeof(s32));
  846                 if (error)
  847                         return (error);
  848                 CP(s32, s, tv_sec);
  849                 CP(s32, s, tv_usec);
  850                 error = copyout(&s, p, sizeof(s));
  851                 if (error)
  852                         return (error);
  853         }
  854         op32 = uap->olddelta;
  855         if (op32) {
  856                 sg = stackgap_init();
  857                 op = stackgap_alloc(&sg, sizeof(struct timeval));
  858                 uap->olddelta = (struct timeval32 *)op;
  859         }
  860         error = utimes(td, (struct utimes_args *) uap);
  861         if (error)
  862                 return error;
  863         if (op32) {
  864                 error = copyin(op, &s, sizeof(s));
  865                 if (error)
  866                         return (error);
  867                 CP(s, s32, tv_sec);
  868                 CP(s, s32, tv_usec);
  869                 error = copyout(&s32, op32, sizeof(s32));
  870         }
  871         return (error);
  872 }
  873 
  874 #ifdef COMPAT_FREEBSD4
  875 int
  876 freebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap)
  877 {
  878         int error;
  879         caddr_t sg;
  880         struct statfs32 *p32, s32;
  881         struct statfs *p = NULL, s;
  882 
  883         p32 = uap->buf;
  884         if (p32) {
  885                 sg = stackgap_init();
  886                 p = stackgap_alloc(&sg, sizeof(struct statfs));
  887                 uap->buf = (struct statfs32 *)p;
  888         }
  889         error = statfs(td, (struct statfs_args *) uap);
  890         if (error)
  891                 return (error);
  892         if (p32) {
  893                 error = copyin(p, &s, sizeof(s));
  894                 if (error)
  895                         return (error);
  896                 copy_statfs(&s, &s32);
  897                 error = copyout(&s32, p32, sizeof(s32));
  898         }
  899         return (error);
  900 }
  901 #endif
  902 
  903 #ifdef COMPAT_FREEBSD4
  904 int
  905 freebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap)
  906 {
  907         int error;
  908         caddr_t sg;
  909         struct statfs32 *p32, s32;
  910         struct statfs *p = NULL, s;
  911 
  912         p32 = uap->buf;
  913         if (p32) {
  914                 sg = stackgap_init();
  915                 p = stackgap_alloc(&sg, sizeof(struct statfs));
  916                 uap->buf = (struct statfs32 *)p;
  917         }
  918         error = fstatfs(td, (struct fstatfs_args *) uap);
  919         if (error)
  920                 return (error);
  921         if (p32) {
  922                 error = copyin(p, &s, sizeof(s));
  923                 if (error)
  924                         return (error);
  925                 copy_statfs(&s, &s32);
  926                 error = copyout(&s32, p32, sizeof(s32));
  927         }
  928         return (error);
  929 }
  930 #endif
  931 
  932 #ifdef COMPAT_FREEBSD4
  933 int
  934 freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap)
  935 {
  936         int error;
  937         caddr_t sg;
  938         struct statfs32 *p32, s32;
  939         struct statfs *p = NULL, s;
  940 
  941         p32 = uap->buf;
  942         if (p32) {
  943                 sg = stackgap_init();
  944                 p = stackgap_alloc(&sg, sizeof(struct statfs));
  945                 uap->buf = (struct statfs32 *)p;
  946         }
  947         error = fhstatfs(td, (struct fhstatfs_args *) uap);
  948         if (error)
  949                 return (error);
  950         if (p32) {
  951                 error = copyin(p, &s, sizeof(s));
  952                 if (error)
  953                         return (error);
  954                 copy_statfs(&s, &s32);
  955                 error = copyout(&s32, p32, sizeof(s32));
  956         }
  957         return (error);
  958 }
  959 #endif
  960 
  961 int
  962 freebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
  963 {
  964         /*
  965          * Vector through to semsys if it is loaded.
  966          */
  967         return sysent[169].sy_call(td, uap);
  968 }
  969 
  970 int
  971 freebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap)
  972 {
  973         /*
  974          * Vector through to msgsys if it is loaded.
  975          */
  976         return sysent[170].sy_call(td, uap);
  977 }
  978 
  979 int
  980 freebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap)
  981 {
  982         /*
  983          * Vector through to shmsys if it is loaded.
  984          */
  985         return sysent[171].sy_call(td, uap);
  986 }
  987 
  988 int
  989 freebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap)
  990 {
  991         struct pread_args ap;
  992 
  993         ap.fd = uap->fd;
  994         ap.buf = uap->buf;
  995         ap.nbyte = uap->nbyte;
  996         ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
  997         return (pread(td, &ap));
  998 }
  999 
 1000 int
 1001 freebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap)
 1002 {
 1003         struct pwrite_args ap;
 1004 
 1005         ap.fd = uap->fd;
 1006         ap.buf = uap->buf;
 1007         ap.nbyte = uap->nbyte;
 1008         ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
 1009         return (pwrite(td, &ap));
 1010 }
 1011 
 1012 int
 1013 freebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap)
 1014 {
 1015         int error;
 1016         struct lseek_args ap;
 1017         off_t pos;
 1018 
 1019         ap.fd = uap->fd;
 1020         ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
 1021         ap.whence = uap->whence;
 1022         error = lseek(td, &ap);
 1023         /* Expand the quad return into two parts for eax and edx */
 1024         pos = *(off_t *)(td->td_retval);
 1025         td->td_retval[0] = pos & 0xffffffff;    /* %eax */
 1026         td->td_retval[1] = pos >> 32;           /* %edx */
 1027         return error;
 1028 }
 1029 
 1030 int
 1031 freebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap)
 1032 {
 1033         struct truncate_args ap;
 1034 
 1035         ap.path = uap->path;
 1036         ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
 1037         return (truncate(td, &ap));
 1038 }
 1039 
 1040 int
 1041 freebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap)
 1042 {
 1043         struct ftruncate_args ap;
 1044 
 1045         ap.fd = uap->fd;
 1046         ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32));
 1047         return (ftruncate(td, &ap));
 1048 }
 1049 
 1050 #ifdef COMPAT_FREEBSD4
 1051 int
 1052 freebsd4_freebsd32_sendfile(struct thread *td,
 1053     struct freebsd4_freebsd32_sendfile_args *uap)
 1054 {
 1055         struct freebsd4_sendfile_args ap;
 1056 
 1057         ap.fd = uap->fd;
 1058         ap.s = uap->s;
 1059         ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
 1060         ap.nbytes = uap->nbytes;        /* XXX check */
 1061         ap.hdtr = uap->hdtr;            /* XXX check */
 1062         ap.sbytes = uap->sbytes;        /* XXX FIXME!! */
 1063         ap.flags = uap->flags;
 1064         return (freebsd4_sendfile(td, &ap));
 1065 }
 1066 #endif
 1067 
 1068 int
 1069 freebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap)
 1070 {
 1071         struct sendfile_args ap;
 1072 
 1073         ap.fd = uap->fd;
 1074         ap.s = uap->s;
 1075         ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));
 1076         ap.nbytes = uap->nbytes;        /* XXX check */
 1077         ap.hdtr = uap->hdtr;            /* XXX check */
 1078         ap.sbytes = uap->sbytes;        /* XXX FIXME!! */
 1079         ap.flags = uap->flags;
 1080         return (sendfile(td, &ap));
 1081 }
 1082 
 1083 struct stat32 {
 1084         dev_t   st_dev;
 1085         ino_t   st_ino;
 1086         mode_t  st_mode;
 1087         nlink_t st_nlink;
 1088         uid_t   st_uid;
 1089         gid_t   st_gid;
 1090         dev_t   st_rdev;
 1091         struct timespec32 st_atimespec;
 1092         struct timespec32 st_mtimespec;
 1093         struct timespec32 st_ctimespec;
 1094         off_t   st_size;
 1095         int64_t st_blocks;
 1096         u_int32_t st_blksize;
 1097         u_int32_t st_flags;
 1098         u_int32_t st_gen;
 1099         struct timespec32 st_birthtimespec;
 1100         unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32));
 1101         unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32));
 1102 };
 1103 
 1104 
 1105 CTASSERT(sizeof(struct stat32) == 96);
 1106 
 1107 static void
 1108 copy_stat( struct stat *in, struct stat32 *out)
 1109 {
 1110         CP(*in, *out, st_dev);
 1111         CP(*in, *out, st_ino);
 1112         CP(*in, *out, st_mode);
 1113         CP(*in, *out, st_nlink);
 1114         CP(*in, *out, st_uid);
 1115         CP(*in, *out, st_gid);
 1116         CP(*in, *out, st_rdev);
 1117         TS_CP(*in, *out, st_atimespec);
 1118         TS_CP(*in, *out, st_mtimespec);
 1119         TS_CP(*in, *out, st_ctimespec);
 1120         CP(*in, *out, st_size);
 1121         CP(*in, *out, st_blocks);
 1122         CP(*in, *out, st_blksize);
 1123         CP(*in, *out, st_flags);
 1124         CP(*in, *out, st_gen);
 1125 }
 1126 
 1127 int
 1128 freebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap)
 1129 {
 1130         struct stat sb;
 1131         struct stat32 sb32;
 1132         int error;
 1133         struct nameidata nd;
 1134 
 1135 #ifdef LOOKUP_SHARED
 1136         NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | NOOBJ,
 1137             UIO_USERSPACE, uap->path, td);
 1138 #else
 1139         NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
 1140             uap->path, td);
 1141 #endif
 1142         if ((error = namei(&nd)) != 0)
 1143                 return (error);
 1144         error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td);
 1145         NDFREE(&nd, NDF_ONLY_PNBUF);
 1146         vput(nd.ni_vp);
 1147         if (error)
 1148                 return (error);
 1149         copy_stat(&sb, &sb32);
 1150         error = copyout(&sb32, uap->ub, sizeof (sb32));
 1151         return (error);
 1152 }
 1153 
 1154 int
 1155 freebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap)
 1156 {
 1157         struct file *fp;
 1158         struct stat ub;
 1159         struct stat32 ub32;
 1160         int error;
 1161 
 1162         if ((error = fget(td, uap->fd, &fp)) != 0)
 1163                 return (error);
 1164         mtx_lock(&Giant);
 1165         error = fo_stat(fp, &ub, td->td_ucred, td);
 1166         mtx_unlock(&Giant);
 1167         fdrop(fp, td);
 1168         if (error)
 1169                 return (error);
 1170         copy_stat(&ub, &ub32);
 1171         error = copyout(&ub32, uap->ub, sizeof(ub32));
 1172         return (error);
 1173 }
 1174 
 1175 int
 1176 freebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap)
 1177 {
 1178         int error;
 1179         struct vnode *vp;
 1180         struct stat sb;
 1181         struct stat32 sb32;
 1182         struct nameidata nd;
 1183 
 1184         NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
 1185             uap->path, td);
 1186         if ((error = namei(&nd)) != 0)
 1187                 return (error);
 1188         vp = nd.ni_vp;
 1189         error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td);
 1190         NDFREE(&nd, NDF_ONLY_PNBUF);
 1191         vput(vp);
 1192         if (error)
 1193                 return (error);
 1194         copy_stat(&sb, &sb32);
 1195         error = copyout(&sb32, uap->ub, sizeof (sb32));
 1196         return (error);
 1197 }
 1198 
 1199 /*
 1200  * MPSAFE
 1201  */
 1202 int
 1203 freebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap)
 1204 {
 1205         int error, name[CTL_MAXNAME];
 1206         size_t j, oldlen;
 1207 
 1208         if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
 1209                 return (EINVAL);
 1210 
 1211         error = copyin(uap->name, &name, uap->namelen * sizeof(int));
 1212         if (error)
 1213                 return (error);
 1214 
 1215         mtx_lock(&Giant);
 1216 
 1217         if (uap->oldlenp)
 1218                 oldlen = fuword32(uap->oldlenp);
 1219         else
 1220                 oldlen = 0;
 1221         error = userland_sysctl(td, name, uap->namelen,
 1222                 uap->old, &oldlen, 1,
 1223                 uap->new, uap->newlen, &j);
 1224         if (error && error != ENOMEM)
 1225                 goto done2;
 1226         if (uap->oldlenp) {
 1227                 suword32(uap->oldlenp, j);
 1228         }
 1229 done2:
 1230         mtx_unlock(&Giant);
 1231         return (error);
 1232 }
 1233 
 1234 struct sigaction32 {
 1235         u_int32_t       sa_u;
 1236         int             sa_flags;
 1237         sigset_t        sa_mask;
 1238 };
 1239 
 1240 CTASSERT(sizeof(struct sigaction32) == 24);
 1241 
 1242 int
 1243 freebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap)
 1244 {
 1245         struct sigaction32 s32;
 1246         struct sigaction sa, osa, *sap;
 1247         int error;
 1248 
 1249         if (uap->act) {
 1250                 error = copyin(uap->act, &s32, sizeof(s32));
 1251                 if (error)
 1252                         return (error);
 1253                 sa.sa_handler = PTRIN(s32.sa_u);
 1254                 CP(s32, sa, sa_flags);
 1255                 CP(s32, sa, sa_mask);
 1256                 sap = &sa;
 1257         } else
 1258                 sap = NULL;
 1259         error = kern_sigaction(td, uap->sig, sap, &osa, 0);
 1260         if (error != 0 && uap->oact != NULL) {
 1261                 s32.sa_u = PTROUT(osa.sa_handler);
 1262                 CP(osa, s32, sa_flags);
 1263                 CP(osa, s32, sa_mask);
 1264                 error = copyout(&s32, uap->oact, sizeof(s32));
 1265         }
 1266         return (error);
 1267 }
 1268 
 1269 #ifdef COMPAT_FREEBSD4
 1270 int
 1271 freebsd4_freebsd32_sigaction(struct thread *td,
 1272                              struct freebsd4_freebsd32_sigaction_args *uap)
 1273 {
 1274         struct sigaction32 s32;
 1275         struct sigaction sa, osa, *sap;
 1276         int error;
 1277 
 1278         if (uap->act) {
 1279                 error = copyin(uap->act, &s32, sizeof(s32));
 1280                 if (error)
 1281                         return (error);
 1282                 sa.sa_handler = PTRIN(s32.sa_u);
 1283                 CP(s32, sa, sa_flags);
 1284                 CP(s32, sa, sa_mask);
 1285                 sap = &sa;
 1286         } else
 1287                 sap = NULL;
 1288         error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4);
 1289         if (error != 0 && uap->oact != NULL) {
 1290                 s32.sa_u = PTROUT(osa.sa_handler);
 1291                 CP(osa, s32, sa_flags);
 1292                 CP(osa, s32, sa_mask);
 1293                 error = copyout(&s32, uap->oact, sizeof(s32));
 1294         }
 1295         return (error);
 1296 }
 1297 #endif
 1298 
 1299 int
 1300 freebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap)
 1301 {
 1302         struct timespec32 rmt32, rqt32;
 1303         struct timespec rmt, rqt;
 1304         int error;
 1305 
 1306         error = copyin(uap->rqtp, &rqt32, sizeof(rqt));
 1307         if (error)
 1308                 return (error);
 1309 
 1310         CP(rqt32, rqt, tv_sec);
 1311         CP(rqt32, rqt, tv_nsec);
 1312 
 1313         if (uap->rmtp &&
 1314             !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE))
 1315                 return (EFAULT);
 1316         error = kern_nanosleep(td, &rqt, &rmt);
 1317         if (error && uap->rmtp) {
 1318                 int error2;
 1319 
 1320                 CP(rmt, rmt32, tv_sec);
 1321                 CP(rmt, rmt32, tv_nsec);
 1322 
 1323                 error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt));
 1324                 if (error2)
 1325                         error = error2;
 1326         }
 1327         return (error);
 1328 }
 1329 
 1330 #if 0
 1331 
 1332 int
 1333 freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap)
 1334 {
 1335         int error;
 1336         caddr_t sg;
 1337         struct yyy32 *p32, s32;
 1338         struct yyy *p = NULL, s;
 1339 
 1340         p32 = uap->zzz;
 1341         if (p32) {
 1342                 sg = stackgap_init();
 1343                 p = stackgap_alloc(&sg, sizeof(struct yyy));
 1344                 uap->zzz = (struct yyy32 *)p;
 1345                 error = copyin(p32, &s32, sizeof(s32));
 1346                 if (error)
 1347                         return (error);
 1348                 /* translate in */
 1349                 error = copyout(&s, p, sizeof(s));
 1350                 if (error)
 1351                         return (error);
 1352         }
 1353         error = xxx(td, (struct xxx_args *) uap);
 1354         if (error)
 1355                 return (error);
 1356         if (p32) {
 1357                 error = copyin(p, &s, sizeof(s));
 1358                 if (error)
 1359                         return (error);
 1360                 /* translate out */
 1361                 error = copyout(&s32, p32, sizeof(s32));
 1362         }
 1363         return (error);
 1364 }
 1365 
 1366 #endif

Cache object: e5601390a5549c911956c9e4f6500273


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