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

Cache object: 17c3d1d5c0ad506831a1048f59685577


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