freebsd32_misc.c revision 160246
1100384Speter/*- 2100384Speter * Copyright (c) 2002 Doug Rabson 3100384Speter * All rights reserved. 4100384Speter * 5100384Speter * Redistribution and use in source and binary forms, with or without 6100384Speter * modification, are permitted provided that the following conditions 7100384Speter * are met: 8100384Speter * 1. Redistributions of source code must retain the above copyright 9100384Speter * notice, this list of conditions and the following disclaimer. 10100384Speter * 2. Redistributions in binary form must reproduce the above copyright 11100384Speter * notice, this list of conditions and the following disclaimer in the 12100384Speter * documentation and/or other materials provided with the distribution. 13100384Speter * 14100384Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15100384Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16100384Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17100384Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18100384Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19100384Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20100384Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21100384Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22100384Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23100384Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24100384Speter * SUCH DAMAGE. 25100384Speter */ 26100384Speter 27118031Sobrien#include <sys/cdefs.h> 28118031Sobrien__FBSDID("$FreeBSD: head/sys/compat/freebsd32/freebsd32_misc.c 160246 2006-07-10 19:37:43Z jhb $"); 29118031Sobrien 30104738Speter#include "opt_compat.h" 31104738Speter 32100384Speter#include <sys/param.h> 33100384Speter#include <sys/systm.h> 34100384Speter#include <sys/bus.h> 35100384Speter#include <sys/exec.h> 36100384Speter#include <sys/fcntl.h> 37100384Speter#include <sys/filedesc.h> 38123746Speter#include <sys/namei.h> 39100384Speter#include <sys/imgact.h> 40100384Speter#include <sys/kernel.h> 41100384Speter#include <sys/lock.h> 42100384Speter#include <sys/malloc.h> 43100384Speter#include <sys/file.h> /* Must come after sys/malloc.h */ 44151909Sps#include <sys/mbuf.h> 45100384Speter#include <sys/mman.h> 46100384Speter#include <sys/module.h> 47100384Speter#include <sys/mount.h> 48100384Speter#include <sys/mutex.h> 49100384Speter#include <sys/namei.h> 50100384Speter#include <sys/param.h> 51100384Speter#include <sys/proc.h> 52100384Speter#include <sys/reboot.h> 53100384Speter#include <sys/resource.h> 54100384Speter#include <sys/resourcevar.h> 55100384Speter#include <sys/selinfo.h> 56146950Sps#include <sys/eventvar.h> /* Must come after sys/selinfo.h */ 57100384Speter#include <sys/pipe.h> /* Must come after sys/selinfo.h */ 58100384Speter#include <sys/signal.h> 59100384Speter#include <sys/signalvar.h> 60100384Speter#include <sys/socket.h> 61100384Speter#include <sys/socketvar.h> 62100384Speter#include <sys/stat.h> 63150883Sjhb#include <sys/syscall.h> 64113859Sjhb#include <sys/syscallsubr.h> 65100384Speter#include <sys/sysctl.h> 66100384Speter#include <sys/sysent.h> 67100384Speter#include <sys/sysproto.h> 68100384Speter#include <sys/systm.h> 69100384Speter#include <sys/unistd.h> 70100384Speter#include <sys/vnode.h> 71127140Sjhb#include <sys/wait.h> 72157285Sps#include <sys/ipc.h> 73157285Sps#include <sys/shm.h> 74100384Speter 75100384Speter#include <vm/vm.h> 76100384Speter#include <vm/vm_kern.h> 77100384Speter#include <vm/vm_param.h> 78100384Speter#include <vm/pmap.h> 79100384Speter#include <vm/vm_map.h> 80100384Speter#include <vm/vm_object.h> 81100384Speter#include <vm/vm_extern.h> 82100384Speter 83151582Sps#include <machine/cpu.h> 84151582Sps 85119333Speter#include <compat/freebsd32/freebsd32_util.h> 86119333Speter#include <compat/freebsd32/freebsd32.h> 87119333Speter#include <compat/freebsd32/freebsd32_proto.h> 88100384Speter 89121719SpeterCTASSERT(sizeof(struct timeval32) == 8); 90121719SpeterCTASSERT(sizeof(struct timespec32) == 8); 91121719SpeterCTASSERT(sizeof(struct statfs32) == 256); 92121719SpeterCTASSERT(sizeof(struct rusage32) == 72); 93121719Speter 94100384Speterint 95119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) 96100384Speter{ 97127140Sjhb int error, status; 98127140Sjhb struct rusage32 ru32; 99136152Sjhb struct rusage ru, *rup; 100100384Speter 101136152Sjhb if (uap->rusage != NULL) 102136152Sjhb rup = &ru; 103136152Sjhb else 104136152Sjhb rup = NULL; 105136152Sjhb error = kern_wait(td, uap->pid, &status, uap->options, rup); 106100384Speter if (error) 107100384Speter return (error); 108127140Sjhb if (uap->status != NULL) 109127140Sjhb error = copyout(&status, uap->status, sizeof(status)); 110127140Sjhb if (uap->rusage != NULL && error == 0) { 111100384Speter TV_CP(ru, ru32, ru_utime); 112100384Speter TV_CP(ru, ru32, ru_stime); 113100384Speter CP(ru, ru32, ru_maxrss); 114100384Speter CP(ru, ru32, ru_ixrss); 115100384Speter CP(ru, ru32, ru_idrss); 116100384Speter CP(ru, ru32, ru_isrss); 117100384Speter CP(ru, ru32, ru_minflt); 118100384Speter CP(ru, ru32, ru_majflt); 119100384Speter CP(ru, ru32, ru_nswap); 120100384Speter CP(ru, ru32, ru_inblock); 121100384Speter CP(ru, ru32, ru_oublock); 122100384Speter CP(ru, ru32, ru_msgsnd); 123100384Speter CP(ru, ru32, ru_msgrcv); 124100384Speter CP(ru, ru32, ru_nsignals); 125100384Speter CP(ru, ru32, ru_nvcsw); 126100384Speter CP(ru, ru32, ru_nivcsw); 127127140Sjhb error = copyout(&ru32, uap->rusage, sizeof(ru32)); 128100384Speter } 129100384Speter return (error); 130100384Speter} 131100384Speter 132128597Smarcel#ifdef COMPAT_FREEBSD4 133100384Speterstatic void 134100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out) 135100384Speter{ 136156266Sps 137156266Sps bzero(out, sizeof(*out)); 138100384Speter CP(*in, *out, f_bsize); 139100384Speter CP(*in, *out, f_iosize); 140100384Speter CP(*in, *out, f_blocks); 141100384Speter CP(*in, *out, f_bfree); 142100384Speter CP(*in, *out, f_bavail); 143100384Speter CP(*in, *out, f_files); 144100384Speter CP(*in, *out, f_ffree); 145100384Speter CP(*in, *out, f_fsid); 146100384Speter CP(*in, *out, f_owner); 147100384Speter CP(*in, *out, f_type); 148100384Speter CP(*in, *out, f_flags); 149100384Speter CP(*in, *out, f_flags); 150100384Speter CP(*in, *out, f_syncwrites); 151100384Speter CP(*in, *out, f_asyncwrites); 152156266Sps strlcpy(out->f_fstypename, 153156266Sps in->f_fstypename, MFSNAMELEN); 154156266Sps strlcpy(out->f_mntonname, 155156266Sps in->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 156100384Speter CP(*in, *out, f_syncreads); 157100384Speter CP(*in, *out, f_asyncreads); 158156266Sps strlcpy(out->f_mntfromname, 159156266Sps in->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 160100384Speter} 161128597Smarcel#endif 162100384Speter 163128597Smarcel#ifdef COMPAT_FREEBSD4 164100384Speterint 165128260Speterfreebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap) 166100384Speter{ 167147178Spjd struct statfs *buf, *sp; 168147178Spjd struct statfs32 stat32; 169147178Spjd size_t count, size; 170100384Speter int error; 171100384Speter 172147178Spjd count = uap->bufsize / sizeof(struct statfs32); 173147178Spjd size = count * sizeof(struct statfs); 174147302Spjd error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags); 175147302Spjd if (size > 0) { 176100384Speter count = td->td_retval[0]; 177147178Spjd sp = buf; 178147178Spjd while (count > 0 && error == 0) { 179147178Spjd copy_statfs(sp, &stat32); 180147178Spjd error = copyout(&stat32, uap->buf, sizeof(stat32)); 181147178Spjd sp++; 182147178Spjd uap->buf++; 183147178Spjd count--; 184100384Speter } 185147178Spjd free(buf, M_TEMP); 186100384Speter } 187100384Speter return (error); 188100384Speter} 189128597Smarcel#endif 190100384Speter 191100384Speterstruct sigaltstack32 { 192100384Speter u_int32_t ss_sp; 193100384Speter u_int32_t ss_size; 194100384Speter int ss_flags; 195100384Speter}; 196100384Speter 197121719SpeterCTASSERT(sizeof(struct sigaltstack32) == 12); 198121719Speter 199100384Speterint 200119333Speterfreebsd32_sigaltstack(struct thread *td, 201119333Speter struct freebsd32_sigaltstack_args *uap) 202100384Speter{ 203113859Sjhb struct sigaltstack32 s32; 204113859Sjhb struct sigaltstack ss, oss, *ssp; 205100384Speter int error; 206100384Speter 207113859Sjhb if (uap->ss != NULL) { 208113859Sjhb error = copyin(uap->ss, &s32, sizeof(s32)); 209100384Speter if (error) 210100384Speter return (error); 211113859Sjhb PTRIN_CP(s32, ss, ss_sp); 212113859Sjhb CP(s32, ss, ss_size); 213113859Sjhb CP(s32, ss, ss_flags); 214113859Sjhb ssp = &ss; 215113859Sjhb } else 216113859Sjhb ssp = NULL; 217113859Sjhb error = kern_sigaltstack(td, ssp, &oss); 218113859Sjhb if (error == 0 && uap->oss != NULL) { 219113859Sjhb PTROUT_CP(oss, s32, ss_sp); 220113859Sjhb CP(oss, s32, ss_size); 221113859Sjhb CP(oss, s32, ss_flags); 222113859Sjhb error = copyout(&s32, uap->oss, sizeof(s32)); 223100384Speter } 224100384Speter return (error); 225100384Speter} 226100384Speter 227142059Sjhb/* 228142059Sjhb * Custom version of exec_copyin_args() so that we can translate 229142059Sjhb * the pointers. 230142059Sjhb */ 231142059Sjhbstatic int 232142059Sjhbfreebsd32_exec_copyin_args(struct image_args *args, char *fname, 233142059Sjhb enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv) 234100384Speter{ 235142059Sjhb char *argp, *envp; 236142059Sjhb u_int32_t *p32, arg; 237142059Sjhb size_t length; 238100384Speter int error; 239100384Speter 240142059Sjhb bzero(args, sizeof(*args)); 241142059Sjhb if (argv == NULL) 242142059Sjhb return (EFAULT); 243100384Speter 244142059Sjhb /* 245142059Sjhb * Allocate temporary demand zeroed space for argument and 246142059Sjhb * environment strings 247142059Sjhb */ 248147588Sjhb args->buf = (char *) kmem_alloc_wait(exec_map, 249147588Sjhb PATH_MAX + ARG_MAX + MAXSHELLCMDLEN); 250142059Sjhb if (args->buf == NULL) 251142059Sjhb return (ENOMEM); 252142059Sjhb args->begin_argv = args->buf; 253142059Sjhb args->endp = args->begin_argv; 254142059Sjhb args->stringspace = ARG_MAX; 255142059Sjhb 256142059Sjhb args->fname = args->buf + ARG_MAX; 257142059Sjhb 258142059Sjhb /* 259142059Sjhb * Copy the file name. 260142059Sjhb */ 261142059Sjhb error = (segflg == UIO_SYSSPACE) ? 262142059Sjhb copystr(fname, args->fname, PATH_MAX, &length) : 263142059Sjhb copyinstr(fname, args->fname, PATH_MAX, &length); 264142059Sjhb if (error != 0) 265156440Sups goto err_exit; 266142059Sjhb 267142059Sjhb /* 268142059Sjhb * extract arguments first 269142059Sjhb */ 270142059Sjhb p32 = argv; 271142059Sjhb for (;;) { 272142059Sjhb error = copyin(p32++, &arg, sizeof(arg)); 273142059Sjhb if (error) 274156440Sups goto err_exit; 275142059Sjhb if (arg == 0) 276142059Sjhb break; 277142059Sjhb argp = PTRIN(arg); 278142059Sjhb error = copyinstr(argp, args->endp, args->stringspace, &length); 279142059Sjhb if (error) { 280142059Sjhb if (error == ENAMETOOLONG) 281156440Sups error = E2BIG; 282156440Sups goto err_exit; 283142059Sjhb } 284142059Sjhb args->stringspace -= length; 285142059Sjhb args->endp += length; 286142059Sjhb args->argc++; 287100384Speter } 288142059Sjhb 289142059Sjhb args->begin_envv = args->endp; 290142059Sjhb 291142059Sjhb /* 292142059Sjhb * extract environment strings 293142059Sjhb */ 294142059Sjhb if (envv) { 295142059Sjhb p32 = envv; 296142059Sjhb for (;;) { 297100384Speter error = copyin(p32++, &arg, sizeof(arg)); 298100384Speter if (error) 299156440Sups goto err_exit; 300142059Sjhb if (arg == 0) 301142059Sjhb break; 302142059Sjhb envp = PTRIN(arg); 303142059Sjhb error = copyinstr(envp, args->endp, args->stringspace, 304142059Sjhb &length); 305142059Sjhb if (error) { 306142059Sjhb if (error == ENAMETOOLONG) 307156440Sups error = E2BIG; 308156440Sups goto err_exit; 309142059Sjhb } 310142059Sjhb args->stringspace -= length; 311142059Sjhb args->endp += length; 312142059Sjhb args->envc++; 313142059Sjhb } 314100384Speter } 315100384Speter 316142059Sjhb return (0); 317156440Sups 318156440Supserr_exit: 319156440Sups kmem_free_wakeup(exec_map, (vm_offset_t)args->buf, 320156440Sups PATH_MAX + ARG_MAX + MAXSHELLCMDLEN); 321156440Sups args->buf = NULL; 322156440Sups return (error); 323100384Speter} 324100384Speter 325142059Sjhbint 326142059Sjhbfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) 327142059Sjhb{ 328142059Sjhb struct image_args eargs; 329142059Sjhb int error; 330142059Sjhb 331142059Sjhb error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE, 332142059Sjhb uap->argv, uap->envv); 333142059Sjhb if (error == 0) 334142059Sjhb error = kern_execve(td, &eargs, NULL); 335142059Sjhb return (error); 336142059Sjhb} 337142059Sjhb 338114987Speter#ifdef __ia64__ 339100384Speterstatic int 340119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 341119333Speter int prot, int fd, off_t pos) 342100384Speter{ 343100384Speter vm_map_t map; 344100384Speter vm_map_entry_t entry; 345100384Speter int rv; 346100384Speter 347100384Speter map = &td->td_proc->p_vmspace->vm_map; 348100384Speter if (fd != -1) 349100384Speter prot |= VM_PROT_WRITE; 350100384Speter 351100384Speter if (vm_map_lookup_entry(map, start, &entry)) { 352100384Speter if ((entry->protection & prot) != prot) { 353100384Speter rv = vm_map_protect(map, 354100384Speter trunc_page(start), 355100384Speter round_page(end), 356100384Speter entry->protection | prot, 357100384Speter FALSE); 358100384Speter if (rv != KERN_SUCCESS) 359100384Speter return (EINVAL); 360100384Speter } 361100384Speter } else { 362100384Speter vm_offset_t addr = trunc_page(start); 363100384Speter rv = vm_map_find(map, 0, 0, 364100384Speter &addr, PAGE_SIZE, FALSE, prot, 365100384Speter VM_PROT_ALL, 0); 366100384Speter if (rv != KERN_SUCCESS) 367100384Speter return (EINVAL); 368100384Speter } 369100384Speter 370100384Speter if (fd != -1) { 371100384Speter struct pread_args r; 372107849Salfred r.fd = fd; 373107849Salfred r.buf = (void *) start; 374107849Salfred r.nbyte = end - start; 375107849Salfred r.offset = pos; 376100384Speter return (pread(td, &r)); 377100384Speter } else { 378100384Speter while (start < end) { 379100384Speter subyte((void *) start, 0); 380100384Speter start++; 381100384Speter } 382100384Speter return (0); 383100384Speter } 384100384Speter} 385114987Speter#endif 386100384Speter 387100384Speterint 388119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) 389100384Speter{ 390100384Speter struct mmap_args ap; 391107849Salfred vm_offset_t addr = (vm_offset_t) uap->addr; 392107849Salfred vm_size_t len = uap->len; 393107849Salfred int prot = uap->prot; 394107849Salfred int flags = uap->flags; 395107849Salfred int fd = uap->fd; 396107849Salfred off_t pos = (uap->poslo 397107849Salfred | ((off_t)uap->poshi << 32)); 398114987Speter#ifdef __ia64__ 399100384Speter vm_size_t pageoff; 400100384Speter int error; 401100384Speter 402100384Speter /* 403100384Speter * Attempt to handle page size hassles. 404100384Speter */ 405100384Speter pageoff = (pos & PAGE_MASK); 406100384Speter if (flags & MAP_FIXED) { 407100384Speter vm_offset_t start, end; 408100384Speter start = addr; 409100384Speter end = addr + len; 410100384Speter 411147964Sjhb mtx_lock(&Giant); 412100384Speter if (start != trunc_page(start)) { 413119333Speter error = freebsd32_mmap_partial(td, start, 414119333Speter round_page(start), prot, 415119333Speter fd, pos); 416100384Speter if (fd != -1) 417100384Speter pos += round_page(start) - start; 418100384Speter start = round_page(start); 419100384Speter } 420100384Speter if (end != round_page(end)) { 421100384Speter vm_offset_t t = trunc_page(end); 422119333Speter error = freebsd32_mmap_partial(td, t, end, 423100384Speter prot, fd, 424100384Speter pos + t - start); 425100384Speter end = trunc_page(end); 426100384Speter } 427100384Speter if (end > start && fd != -1 && (pos & PAGE_MASK)) { 428100384Speter /* 429100384Speter * We can't map this region at all. The specified 430100384Speter * address doesn't have the same alignment as the file 431100384Speter * position. Fake the mapping by simply reading the 432100384Speter * entire region into memory. First we need to make 433100384Speter * sure the region exists. 434100384Speter */ 435100384Speter vm_map_t map; 436100384Speter struct pread_args r; 437100384Speter int rv; 438100384Speter 439100384Speter prot |= VM_PROT_WRITE; 440100384Speter map = &td->td_proc->p_vmspace->vm_map; 441100384Speter rv = vm_map_remove(map, start, end); 442147964Sjhb if (rv != KERN_SUCCESS) { 443147964Sjhb mtx_unlock(&Giant); 444100384Speter return (EINVAL); 445147964Sjhb } 446100384Speter rv = vm_map_find(map, 0, 0, 447100384Speter &start, end - start, FALSE, 448100384Speter prot, VM_PROT_ALL, 0); 449147964Sjhb mtx_unlock(&Giant); 450100384Speter if (rv != KERN_SUCCESS) 451100384Speter return (EINVAL); 452107849Salfred r.fd = fd; 453107849Salfred r.buf = (void *) start; 454107849Salfred r.nbyte = end - start; 455107849Salfred r.offset = pos; 456100384Speter error = pread(td, &r); 457100384Speter if (error) 458100384Speter return (error); 459100384Speter 460100384Speter td->td_retval[0] = addr; 461100384Speter return (0); 462100384Speter } 463147964Sjhb mtx_unlock(&Giant); 464100384Speter if (end == start) { 465100384Speter /* 466100384Speter * After dealing with the ragged ends, there 467100384Speter * might be none left. 468100384Speter */ 469100384Speter td->td_retval[0] = addr; 470100384Speter return (0); 471100384Speter } 472100384Speter addr = start; 473100384Speter len = end - start; 474100384Speter } 475114987Speter#endif 476100384Speter 477107849Salfred ap.addr = (void *) addr; 478107849Salfred ap.len = len; 479107849Salfred ap.prot = prot; 480107849Salfred ap.flags = flags; 481107849Salfred ap.fd = fd; 482107849Salfred ap.pos = pos; 483100384Speter 484100384Speter return (mmap(td, &ap)); 485100384Speter} 486100384Speter 487100384Speterstruct itimerval32 { 488100384Speter struct timeval32 it_interval; 489100384Speter struct timeval32 it_value; 490100384Speter}; 491100384Speter 492121719SpeterCTASSERT(sizeof(struct itimerval32) == 16); 493121719Speter 494100384Speterint 495119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap) 496100384Speter{ 497142059Sjhb struct itimerval itv, oitv, *itvp; 498142059Sjhb struct itimerval32 i32; 499100384Speter int error; 500100384Speter 501142059Sjhb if (uap->itv != NULL) { 502142059Sjhb error = copyin(uap->itv, &i32, sizeof(i32)); 503100384Speter if (error) 504100384Speter return (error); 505142059Sjhb TV_CP(i32, itv, it_interval); 506142059Sjhb TV_CP(i32, itv, it_value); 507142059Sjhb itvp = &itv; 508142059Sjhb } else 509142059Sjhb itvp = NULL; 510142059Sjhb error = kern_setitimer(td, uap->which, itvp, &oitv); 511142059Sjhb if (error || uap->oitv == NULL) 512100384Speter return (error); 513142059Sjhb TV_CP(oitv, i32, it_interval); 514142059Sjhb TV_CP(oitv, i32, it_value); 515142059Sjhb return (copyout(&i32, uap->oitv, sizeof(i32))); 516100384Speter} 517100384Speter 518100384Speterint 519125171Speterfreebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap) 520125171Speter{ 521142059Sjhb struct itimerval itv; 522142059Sjhb struct itimerval32 i32; 523125171Speter int error; 524125171Speter 525142059Sjhb error = kern_getitimer(td, uap->which, &itv); 526142059Sjhb if (error || uap->itv == NULL) 527125171Speter return (error); 528142059Sjhb TV_CP(itv, i32, it_interval); 529142059Sjhb TV_CP(itv, i32, it_value); 530142059Sjhb return (copyout(&i32, uap->itv, sizeof(i32))); 531125171Speter} 532125171Speter 533125171Speterint 534119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap) 535100384Speter{ 536142059Sjhb struct timeval32 tv32; 537142059Sjhb struct timeval tv, *tvp; 538100384Speter int error; 539100384Speter 540142059Sjhb if (uap->tv != NULL) { 541142059Sjhb error = copyin(uap->tv, &tv32, sizeof(tv32)); 542100384Speter if (error) 543100384Speter return (error); 544142059Sjhb CP(tv32, tv, tv_sec); 545142059Sjhb CP(tv32, tv, tv_usec); 546142059Sjhb tvp = &tv; 547142059Sjhb } else 548142059Sjhb tvp = NULL; 549100384Speter /* 550100384Speter * XXX big-endian needs to convert the fd_sets too. 551142059Sjhb * XXX Do pointers need PTRIN()? 552100384Speter */ 553142059Sjhb return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp)); 554100384Speter} 555100384Speter 556114987Speterstruct kevent32 { 557114987Speter u_int32_t ident; /* identifier for this event */ 558114987Speter short filter; /* filter for event */ 559114987Speter u_short flags; 560114987Speter u_int fflags; 561114987Speter int32_t data; 562114987Speter u_int32_t udata; /* opaque user data identifier */ 563114987Speter}; 564114987Speter 565121719SpeterCTASSERT(sizeof(struct kevent32) == 20); 566146950Spsstatic int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count); 567146950Spsstatic int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count); 568121719Speter 569146950Sps/* 570146950Sps * Copy 'count' items into the destination list pointed to by uap->eventlist. 571146950Sps */ 572146950Spsstatic int 573146950Spsfreebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count) 574146950Sps{ 575146950Sps struct freebsd32_kevent_args *uap; 576146950Sps struct kevent32 ks32[KQ_NEVENTS]; 577146950Sps int i, error = 0; 578146950Sps 579146950Sps KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count)); 580146950Sps uap = (struct freebsd32_kevent_args *)arg; 581146950Sps 582146950Sps for (i = 0; i < count; i++) { 583146950Sps CP(kevp[i], ks32[i], ident); 584146950Sps CP(kevp[i], ks32[i], filter); 585146950Sps CP(kevp[i], ks32[i], flags); 586146950Sps CP(kevp[i], ks32[i], fflags); 587146950Sps CP(kevp[i], ks32[i], data); 588146950Sps PTROUT_CP(kevp[i], ks32[i], udata); 589146950Sps } 590146950Sps error = copyout(ks32, uap->eventlist, count * sizeof *ks32); 591146950Sps if (error == 0) 592146950Sps uap->eventlist += count; 593146950Sps return (error); 594146950Sps} 595146950Sps 596146950Sps/* 597146950Sps * Copy 'count' items from the list pointed to by uap->changelist. 598146950Sps */ 599146950Spsstatic int 600146950Spsfreebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count) 601146950Sps{ 602146950Sps struct freebsd32_kevent_args *uap; 603146950Sps struct kevent32 ks32[KQ_NEVENTS]; 604146950Sps int i, error = 0; 605146950Sps 606146950Sps KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count)); 607146950Sps uap = (struct freebsd32_kevent_args *)arg; 608146950Sps 609146950Sps error = copyin(uap->changelist, ks32, count * sizeof *ks32); 610146950Sps if (error) 611146950Sps goto done; 612146950Sps uap->changelist += count; 613146950Sps 614146950Sps for (i = 0; i < count; i++) { 615146950Sps CP(ks32[i], kevp[i], ident); 616146950Sps CP(ks32[i], kevp[i], filter); 617146950Sps CP(ks32[i], kevp[i], flags); 618146950Sps CP(ks32[i], kevp[i], fflags); 619146950Sps CP(ks32[i], kevp[i], data); 620146950Sps PTRIN_CP(ks32[i], kevp[i], udata); 621146950Sps } 622146950Spsdone: 623146950Sps return (error); 624146950Sps} 625146950Sps 626100384Speterint 627119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap) 628114987Speter{ 629114987Speter struct timespec32 ts32; 630142934Sps struct timespec ts, *tsp; 631146950Sps struct kevent_copyops k_ops = { uap, 632146950Sps freebsd32_kevent_copyout, 633146950Sps freebsd32_kevent_copyin}; 634146950Sps int error; 635114987Speter 636114987Speter 637114987Speter if (uap->timeout) { 638114987Speter error = copyin(uap->timeout, &ts32, sizeof(ts32)); 639114987Speter if (error) 640114987Speter return (error); 641114987Speter CP(ts32, ts, tv_sec); 642114987Speter CP(ts32, ts, tv_nsec); 643142934Sps tsp = &ts; 644142934Sps } else 645142934Sps tsp = NULL; 646146950Sps error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents, 647146950Sps &k_ops, tsp); 648142934Sps return (error); 649114987Speter} 650114987Speter 651114987Speterint 652119333Speterfreebsd32_gettimeofday(struct thread *td, 653119333Speter struct freebsd32_gettimeofday_args *uap) 654100384Speter{ 655123425Speter struct timeval atv; 656123425Speter struct timeval32 atv32; 657123425Speter struct timezone rtz; 658123425Speter int error = 0; 659100384Speter 660123425Speter if (uap->tp) { 661123425Speter microtime(&atv); 662123425Speter CP(atv, atv32, tv_sec); 663123425Speter CP(atv, atv32, tv_usec); 664123425Speter error = copyout(&atv32, uap->tp, sizeof (atv32)); 665100384Speter } 666123425Speter if (error == 0 && uap->tzp != NULL) { 667123425Speter rtz.tz_minuteswest = tz_minuteswest; 668123425Speter rtz.tz_dsttime = tz_dsttime; 669123425Speter error = copyout(&rtz, uap->tzp, sizeof (rtz)); 670100384Speter } 671100384Speter return (error); 672100384Speter} 673100384Speter 674100384Speterint 675119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap) 676100384Speter{ 677136152Sjhb struct rusage32 s32; 678136152Sjhb struct rusage s; 679100384Speter int error; 680100384Speter 681136152Sjhb error = kern_getrusage(td, uap->who, &s); 682100384Speter if (error) 683100384Speter return (error); 684136152Sjhb if (uap->rusage != NULL) { 685100384Speter TV_CP(s, s32, ru_utime); 686100384Speter TV_CP(s, s32, ru_stime); 687100384Speter CP(s, s32, ru_maxrss); 688100384Speter CP(s, s32, ru_ixrss); 689100384Speter CP(s, s32, ru_idrss); 690100384Speter CP(s, s32, ru_isrss); 691100384Speter CP(s, s32, ru_minflt); 692100384Speter CP(s, s32, ru_majflt); 693100384Speter CP(s, s32, ru_nswap); 694100384Speter CP(s, s32, ru_inblock); 695100384Speter CP(s, s32, ru_oublock); 696100384Speter CP(s, s32, ru_msgsnd); 697100384Speter CP(s, s32, ru_msgrcv); 698100384Speter CP(s, s32, ru_nsignals); 699100384Speter CP(s, s32, ru_nvcsw); 700100384Speter CP(s, s32, ru_nivcsw); 701136152Sjhb error = copyout(&s32, uap->rusage, sizeof(s32)); 702100384Speter } 703100384Speter return (error); 704100384Speter} 705100384Speter 706100384Speterstruct iovec32 { 707100384Speter u_int32_t iov_base; 708100384Speter int iov_len; 709100384Speter}; 710100384Speter 711121719SpeterCTASSERT(sizeof(struct iovec32) == 8); 712121719Speter 713144450Sjhbstatic int 714144450Sjhbfreebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop) 715100384Speter{ 716144450Sjhb struct iovec32 iov32; 717144450Sjhb struct iovec *iov; 718144450Sjhb struct uio *uio; 719144450Sjhb u_int iovlen; 720144450Sjhb int error, i; 721100384Speter 722144450Sjhb *uiop = NULL; 723144450Sjhb if (iovcnt > UIO_MAXIOV) 724100384Speter return (EINVAL); 725144450Sjhb iovlen = iovcnt * sizeof(struct iovec); 726144450Sjhb uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK); 727144450Sjhb iov = (struct iovec *)(uio + 1); 728144450Sjhb for (i = 0; i < iovcnt; i++) { 729144450Sjhb error = copyin(&iovp[i], &iov32, sizeof(struct iovec32)); 730144450Sjhb if (error) { 731144450Sjhb free(uio, M_IOV); 732144450Sjhb return (error); 733144450Sjhb } 734144450Sjhb iov[i].iov_base = PTRIN(iov32.iov_base); 735144450Sjhb iov[i].iov_len = iov32.iov_len; 736100384Speter } 737144450Sjhb uio->uio_iov = iov; 738144450Sjhb uio->uio_iovcnt = iovcnt; 739144450Sjhb uio->uio_segflg = UIO_USERSPACE; 740144450Sjhb uio->uio_offset = -1; 741144450Sjhb uio->uio_resid = 0; 742144450Sjhb for (i = 0; i < iovcnt; i++) { 743144450Sjhb if (iov->iov_len > INT_MAX - uio->uio_resid) { 744144450Sjhb free(uio, M_IOV); 745144450Sjhb return (EINVAL); 746144450Sjhb } 747144450Sjhb uio->uio_resid += iov->iov_len; 748144450Sjhb iov++; 749144450Sjhb } 750144450Sjhb *uiop = uio; 751144450Sjhb return (0); 752144450Sjhb} 753100384Speter 754144450Sjhbint 755144450Sjhbfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) 756144450Sjhb{ 757144450Sjhb struct uio *auio; 758144450Sjhb int error; 759100384Speter 760144450Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 761144450Sjhb if (error) 762144450Sjhb return (error); 763144450Sjhb error = kern_readv(td, uap->fd, auio); 764144450Sjhb free(auio, M_IOV); 765100384Speter return (error); 766100384Speter} 767100384Speter 768100384Speterint 769119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) 770100384Speter{ 771144450Sjhb struct uio *auio; 772144450Sjhb int error; 773100384Speter 774144450Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 775144450Sjhb if (error) 776144450Sjhb return (error); 777144450Sjhb error = kern_writev(td, uap->fd, auio); 778144450Sjhb free(auio, M_IOV); 779100384Speter return (error); 780100384Speter} 781100384Speter 782100384Speterint 783147813Sjhbfreebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap) 784147813Sjhb{ 785147813Sjhb struct uio *auio; 786147813Sjhb int error; 787147813Sjhb 788147813Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 789147813Sjhb if (error) 790147813Sjhb return (error); 791147813Sjhb error = kern_preadv(td, uap->fd, auio, uap->offset); 792147813Sjhb free(auio, M_IOV); 793147813Sjhb return (error); 794147813Sjhb} 795147813Sjhb 796147813Sjhbint 797147813Sjhbfreebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap) 798147813Sjhb{ 799147813Sjhb struct uio *auio; 800147813Sjhb int error; 801147813Sjhb 802147813Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 803147813Sjhb if (error) 804147813Sjhb return (error); 805147813Sjhb error = kern_pwritev(td, uap->fd, auio, uap->offset); 806147813Sjhb free(auio, M_IOV); 807147813Sjhb return (error); 808147813Sjhb} 809147813Sjhb 810151359Spsstatic int 811151909Spsfreebsd32_copyiniov(struct iovec32 *iovp32, u_int iovcnt, struct iovec **iovp, 812151359Sps int error) 813151359Sps{ 814151359Sps struct iovec32 iov32; 815151909Sps struct iovec *iov; 816151909Sps u_int iovlen; 817151359Sps int i; 818151359Sps 819151909Sps *iovp = NULL; 820151359Sps if (iovcnt > UIO_MAXIOV) 821151359Sps return (error); 822151359Sps iovlen = iovcnt * sizeof(struct iovec); 823151909Sps iov = malloc(iovlen, M_IOV, M_WAITOK); 824151359Sps for (i = 0; i < iovcnt; i++) { 825151909Sps error = copyin(&iovp32[i], &iov32, sizeof(struct iovec32)); 826151359Sps if (error) { 827151909Sps free(iov, M_IOV); 828151359Sps return (error); 829151359Sps } 830151909Sps iov[i].iov_base = PTRIN(iov32.iov_base); 831151909Sps iov[i].iov_len = iov32.iov_len; 832151359Sps } 833151909Sps *iovp = iov; 834151359Sps return (0); 835151359Sps} 836151359Sps 837151359Spsstruct msghdr32 { 838151359Sps u_int32_t msg_name; 839151359Sps socklen_t msg_namelen; 840151359Sps u_int32_t msg_iov; 841151359Sps int msg_iovlen; 842151359Sps u_int32_t msg_control; 843151359Sps socklen_t msg_controllen; 844151359Sps int msg_flags; 845151359Sps}; 846151359SpsCTASSERT(sizeof(struct msghdr32) == 28); 847151359Sps 848151359Spsstatic int 849151359Spsfreebsd32_copyinmsghdr(struct msghdr32 *msg32, struct msghdr *msg) 850151359Sps{ 851151359Sps struct msghdr32 m32; 852151359Sps int error; 853151359Sps 854151359Sps error = copyin(msg32, &m32, sizeof(m32)); 855151359Sps if (error) 856151359Sps return (error); 857151359Sps msg->msg_name = PTRIN(m32.msg_name); 858151359Sps msg->msg_namelen = m32.msg_namelen; 859151359Sps msg->msg_iov = PTRIN(m32.msg_iov); 860151359Sps msg->msg_iovlen = m32.msg_iovlen; 861151359Sps msg->msg_control = PTRIN(m32.msg_control); 862151359Sps msg->msg_controllen = m32.msg_controllen; 863151359Sps msg->msg_flags = m32.msg_flags; 864151909Sps return (0); 865151359Sps} 866151359Sps 867151359Spsstatic int 868151359Spsfreebsd32_copyoutmsghdr(struct msghdr *msg, struct msghdr32 *msg32) 869151359Sps{ 870151359Sps struct msghdr32 m32; 871151359Sps int error; 872151359Sps 873151359Sps m32.msg_name = PTROUT(msg->msg_name); 874151359Sps m32.msg_namelen = msg->msg_namelen; 875151359Sps m32.msg_iov = PTROUT(msg->msg_iov); 876151359Sps m32.msg_iovlen = msg->msg_iovlen; 877151359Sps m32.msg_control = PTROUT(msg->msg_control); 878151359Sps m32.msg_controllen = msg->msg_controllen; 879151359Sps m32.msg_flags = msg->msg_flags; 880151359Sps error = copyout(&m32, msg32, sizeof(m32)); 881151359Sps return (error); 882151359Sps} 883151359Sps 884151909Sps#define FREEBSD32_ALIGNBYTES (sizeof(int) - 1) 885151909Sps#define FREEBSD32_ALIGN(p) \ 886151909Sps (((u_long)(p) + FREEBSD32_ALIGNBYTES) & ~FREEBSD32_ALIGNBYTES) 887151909Sps#define FREEBSD32_CMSG_SPACE(l) \ 888151909Sps (FREEBSD32_ALIGN(sizeof(struct cmsghdr)) + FREEBSD32_ALIGN(l)) 889151909Sps 890151909Sps#define FREEBSD32_CMSG_DATA(cmsg) ((unsigned char *)(cmsg) + \ 891151909Sps FREEBSD32_ALIGN(sizeof(struct cmsghdr))) 892151909Spsstatic int 893151909Spsfreebsd32_copy_msg_out(struct msghdr *msg, struct mbuf *control) 894151909Sps{ 895151909Sps struct cmsghdr *cm; 896151909Sps void *data; 897151909Sps socklen_t clen, datalen; 898151909Sps int error; 899151909Sps caddr_t ctlbuf; 900151909Sps int len, maxlen, copylen; 901151909Sps struct mbuf *m; 902151909Sps error = 0; 903151909Sps 904151909Sps len = msg->msg_controllen; 905151909Sps maxlen = msg->msg_controllen; 906151909Sps msg->msg_controllen = 0; 907151909Sps 908151909Sps m = control; 909151909Sps ctlbuf = msg->msg_control; 910151909Sps 911151909Sps while (m && len > 0) { 912151909Sps cm = mtod(m, struct cmsghdr *); 913151909Sps clen = m->m_len; 914151909Sps 915151909Sps while (cm != NULL) { 916151909Sps 917151909Sps if (sizeof(struct cmsghdr) > clen || 918151909Sps cm->cmsg_len > clen) { 919151909Sps error = EINVAL; 920151909Sps break; 921151909Sps } 922151909Sps 923151909Sps data = CMSG_DATA(cm); 924151909Sps datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data; 925151909Sps 926151909Sps /* Adjust message length */ 927151909Sps cm->cmsg_len = FREEBSD32_ALIGN(sizeof(struct cmsghdr)) + 928151909Sps datalen; 929151909Sps 930151909Sps 931151909Sps /* Copy cmsghdr */ 932151909Sps copylen = sizeof(struct cmsghdr); 933151909Sps if (len < copylen) { 934151909Sps msg->msg_flags |= MSG_CTRUNC; 935151909Sps copylen = len; 936151909Sps } 937151909Sps 938151909Sps error = copyout(cm,ctlbuf,copylen); 939151909Sps if (error) 940151909Sps goto exit; 941151909Sps 942151909Sps ctlbuf += FREEBSD32_ALIGN(copylen); 943151909Sps len -= FREEBSD32_ALIGN(copylen); 944151909Sps 945151909Sps if (len <= 0) 946151909Sps break; 947151909Sps 948151909Sps /* Copy data */ 949151909Sps copylen = datalen; 950151909Sps if (len < copylen) { 951151909Sps msg->msg_flags |= MSG_CTRUNC; 952151909Sps copylen = len; 953151909Sps } 954151909Sps 955151909Sps error = copyout(data,ctlbuf,copylen); 956151909Sps if (error) 957151909Sps goto exit; 958151909Sps 959151909Sps ctlbuf += FREEBSD32_ALIGN(copylen); 960151909Sps len -= FREEBSD32_ALIGN(copylen); 961151909Sps 962151909Sps if (CMSG_SPACE(datalen) < clen) { 963151909Sps clen -= CMSG_SPACE(datalen); 964151909Sps cm = (struct cmsghdr *) 965151909Sps ((caddr_t)cm + CMSG_SPACE(datalen)); 966151909Sps } else { 967151909Sps clen = 0; 968151909Sps cm = NULL; 969151909Sps } 970151909Sps } 971151909Sps m = m->m_next; 972151909Sps } 973151909Sps 974151909Sps msg->msg_controllen = (len <= 0) ? maxlen : ctlbuf - (caddr_t)msg->msg_control; 975151909Sps 976151909Spsexit: 977151909Sps return (error); 978151909Sps 979151909Sps} 980151909Sps 981147813Sjhbint 982151359Spsfreebsd32_recvmsg(td, uap) 983151359Sps struct thread *td; 984151359Sps struct freebsd32_recvmsg_args /* { 985151359Sps int s; 986151359Sps struct msghdr32 *msg; 987151359Sps int flags; 988151359Sps } */ *uap; 989151359Sps{ 990151359Sps struct msghdr msg; 991151359Sps struct msghdr32 m32; 992151359Sps struct iovec *uiov, *iov; 993151909Sps struct mbuf *control = NULL; 994151909Sps struct mbuf **controlp; 995151909Sps 996151359Sps int error; 997151359Sps error = copyin(uap->msg, &m32, sizeof(m32)); 998151359Sps if (error) 999151359Sps return (error); 1000151359Sps error = freebsd32_copyinmsghdr(uap->msg, &msg); 1001151359Sps if (error) 1002151359Sps return (error); 1003160246Sjhb error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov, 1004160246Sjhb EMSGSIZE); 1005151359Sps if (error) 1006151359Sps return (error); 1007151359Sps msg.msg_flags = uap->flags; 1008151359Sps uiov = msg.msg_iov; 1009151359Sps msg.msg_iov = iov; 1010151909Sps 1011151909Sps controlp = (msg.msg_control != NULL) ? &control : NULL; 1012151909Sps error = kern_recvit(td, uap->s, &msg, NULL, UIO_USERSPACE, controlp); 1013151359Sps if (error == 0) { 1014151359Sps msg.msg_iov = uiov; 1015151909Sps 1016151909Sps if (control != NULL) 1017151909Sps error = freebsd32_copy_msg_out(&msg, control); 1018151909Sps 1019151909Sps if (error == 0) 1020151909Sps error = freebsd32_copyoutmsghdr(&msg, uap->msg); 1021151359Sps } 1022151359Sps free(iov, M_IOV); 1023151909Sps 1024151909Sps if (control != NULL) 1025151909Sps m_freem(control); 1026151909Sps 1027151359Sps return (error); 1028151359Sps} 1029151359Sps 1030151909Sps 1031151909Spsstatic int 1032151909Spsfreebsd32_convert_msg_in(struct mbuf **controlp) 1033151909Sps{ 1034151909Sps struct mbuf *control = *controlp; 1035151909Sps struct cmsghdr *cm = mtod(control, struct cmsghdr *); 1036151909Sps void *data; 1037151909Sps socklen_t clen = control->m_len, datalen; 1038151909Sps int error; 1039151909Sps 1040151909Sps error = 0; 1041151909Sps *controlp = NULL; 1042151909Sps 1043151909Sps while (cm != NULL) { 1044151909Sps if (sizeof(struct cmsghdr) > clen || cm->cmsg_len > clen) { 1045151909Sps error = EINVAL; 1046151909Sps break; 1047151909Sps } 1048151909Sps 1049151909Sps data = FREEBSD32_CMSG_DATA(cm); 1050151909Sps datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data; 1051151909Sps 1052151909Sps *controlp = sbcreatecontrol(data, datalen, cm->cmsg_type, 1053151909Sps cm->cmsg_level); 1054151909Sps controlp = &(*controlp)->m_next; 1055151909Sps 1056151909Sps if (FREEBSD32_CMSG_SPACE(datalen) < clen) { 1057151909Sps clen -= FREEBSD32_CMSG_SPACE(datalen); 1058151909Sps cm = (struct cmsghdr *) 1059151909Sps ((caddr_t)cm + FREEBSD32_CMSG_SPACE(datalen)); 1060151909Sps } else { 1061151909Sps clen = 0; 1062151909Sps cm = NULL; 1063151909Sps } 1064151909Sps } 1065151909Sps 1066151909Sps m_freem(control); 1067151909Sps return (error); 1068151909Sps} 1069151909Sps 1070151909Sps 1071151359Spsint 1072151359Spsfreebsd32_sendmsg(struct thread *td, 1073151359Sps struct freebsd32_sendmsg_args *uap) 1074151359Sps{ 1075151359Sps struct msghdr msg; 1076151359Sps struct msghdr32 m32; 1077151359Sps struct iovec *iov; 1078151909Sps struct mbuf *control = NULL; 1079151909Sps struct sockaddr *to = NULL; 1080151359Sps int error; 1081151359Sps 1082151359Sps error = copyin(uap->msg, &m32, sizeof(m32)); 1083151359Sps if (error) 1084151359Sps return (error); 1085151359Sps error = freebsd32_copyinmsghdr(uap->msg, &msg); 1086151359Sps if (error) 1087151359Sps return (error); 1088160246Sjhb error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov, 1089160246Sjhb EMSGSIZE); 1090151359Sps if (error) 1091151359Sps return (error); 1092151359Sps msg.msg_iov = iov; 1093151909Sps if (msg.msg_name != NULL) { 1094151909Sps error = getsockaddr(&to, msg.msg_name, msg.msg_namelen); 1095151909Sps if (error) { 1096151909Sps to = NULL; 1097151909Sps goto out; 1098151909Sps } 1099151909Sps msg.msg_name = to; 1100151909Sps } 1101151909Sps 1102151909Sps if (msg.msg_control) { 1103151909Sps if (msg.msg_controllen < sizeof(struct cmsghdr)) { 1104151909Sps error = EINVAL; 1105151909Sps goto out; 1106151909Sps } 1107151909Sps 1108151909Sps error = sockargs(&control, msg.msg_control, 1109151909Sps msg.msg_controllen, MT_CONTROL); 1110151909Sps if (error) 1111151909Sps goto out; 1112151909Sps 1113151909Sps error = freebsd32_convert_msg_in(&control); 1114151909Sps if (error) 1115151909Sps goto out; 1116151909Sps } 1117151909Sps 1118151909Sps error = kern_sendit(td, uap->s, &msg, uap->flags, control, 1119151909Sps UIO_USERSPACE); 1120151909Sps 1121151909Spsout: 1122151359Sps free(iov, M_IOV); 1123151909Sps if (to) 1124151909Sps free(to, M_SONAME); 1125151359Sps return (error); 1126151359Sps} 1127151359Sps 1128151359Spsint 1129151359Spsfreebsd32_recvfrom(struct thread *td, 1130151359Sps struct freebsd32_recvfrom_args *uap) 1131151359Sps{ 1132151359Sps struct msghdr msg; 1133151359Sps struct iovec aiov; 1134151359Sps int error; 1135151359Sps 1136151359Sps if (uap->fromlenaddr) { 1137160246Sjhb error = copyin(PTRIN(uap->fromlenaddr), &msg.msg_namelen, 1138160246Sjhb sizeof(msg.msg_namelen)); 1139151359Sps if (error) 1140151359Sps return (error); 1141151359Sps } else { 1142151359Sps msg.msg_namelen = 0; 1143151359Sps } 1144151359Sps 1145160246Sjhb msg.msg_name = PTRIN(uap->from); 1146151359Sps msg.msg_iov = &aiov; 1147151359Sps msg.msg_iovlen = 1; 1148160246Sjhb aiov.iov_base = PTRIN(uap->buf); 1149151359Sps aiov.iov_len = uap->len; 1150160246Sjhb msg.msg_control = NULL; 1151151359Sps msg.msg_flags = uap->flags; 1152160246Sjhb error = kern_recvit(td, uap->s, &msg, PTRIN(uap->fromlenaddr), 1153160246Sjhb UIO_USERSPACE, NULL); 1154151359Sps return (error); 1155151359Sps} 1156151359Sps 1157151359Spsint 1158119333Speterfreebsd32_settimeofday(struct thread *td, 1159119333Speter struct freebsd32_settimeofday_args *uap) 1160100384Speter{ 1161144450Sjhb struct timeval32 tv32; 1162144450Sjhb struct timeval tv, *tvp; 1163144450Sjhb struct timezone tz, *tzp; 1164100384Speter int error; 1165100384Speter 1166144450Sjhb if (uap->tv) { 1167144450Sjhb error = copyin(uap->tv, &tv32, sizeof(tv32)); 1168100384Speter if (error) 1169100384Speter return (error); 1170144450Sjhb CP(tv32, tv, tv_sec); 1171144450Sjhb CP(tv32, tv, tv_usec); 1172144450Sjhb tvp = &tv; 1173144450Sjhb } else 1174144450Sjhb tvp = NULL; 1175144450Sjhb if (uap->tzp) { 1176144450Sjhb error = copyin(uap->tzp, &tz, sizeof(tz)); 1177100384Speter if (error) 1178100384Speter return (error); 1179144450Sjhb tzp = &tz; 1180144450Sjhb } else 1181144450Sjhb tzp = NULL; 1182144450Sjhb return (kern_settimeofday(td, tvp, tzp)); 1183100384Speter} 1184100384Speter 1185100384Speterint 1186119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap) 1187100384Speter{ 1188142059Sjhb struct timeval32 s32[2]; 1189142059Sjhb struct timeval s[2], *sp; 1190100384Speter int error; 1191100384Speter 1192142059Sjhb if (uap->tptr != NULL) { 1193142059Sjhb error = copyin(uap->tptr, s32, sizeof(s32)); 1194100384Speter if (error) 1195100384Speter return (error); 1196100384Speter CP(s32[0], s[0], tv_sec); 1197100384Speter CP(s32[0], s[0], tv_usec); 1198100384Speter CP(s32[1], s[1], tv_sec); 1199100384Speter CP(s32[1], s[1], tv_usec); 1200142059Sjhb sp = s; 1201142059Sjhb } else 1202142059Sjhb sp = NULL; 1203142059Sjhb return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE)); 1204100384Speter} 1205100384Speter 1206100384Speterint 1207154586Sambriskofreebsd32_lutimes(struct thread *td, struct freebsd32_lutimes_args *uap) 1208154586Sambrisko{ 1209154586Sambrisko struct timeval32 s32[2]; 1210154586Sambrisko struct timeval s[2], *sp; 1211154586Sambrisko int error; 1212154586Sambrisko 1213154586Sambrisko if (uap->tptr != NULL) { 1214154586Sambrisko error = copyin(uap->tptr, s32, sizeof(s32)); 1215154586Sambrisko if (error) 1216154586Sambrisko return (error); 1217154586Sambrisko CP(s32[0], s[0], tv_sec); 1218154586Sambrisko CP(s32[0], s[0], tv_usec); 1219154586Sambrisko CP(s32[1], s[1], tv_sec); 1220154586Sambrisko CP(s32[1], s[1], tv_usec); 1221154586Sambrisko sp = s; 1222154586Sambrisko } else 1223154586Sambrisko sp = NULL; 1224154586Sambrisko return (kern_lutimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE)); 1225154586Sambrisko} 1226154586Sambrisko 1227154586Sambriskoint 1228153247Sambriskofreebsd32_futimes(struct thread *td, struct freebsd32_futimes_args *uap) 1229153247Sambrisko{ 1230153247Sambrisko struct timeval32 s32[2]; 1231153247Sambrisko struct timeval s[2], *sp; 1232153247Sambrisko int error; 1233153247Sambrisko 1234153247Sambrisko if (uap->tptr != NULL) { 1235153247Sambrisko error = copyin(uap->tptr, s32, sizeof(s32)); 1236153247Sambrisko if (error) 1237153247Sambrisko return (error); 1238153247Sambrisko CP(s32[0], s[0], tv_sec); 1239153247Sambrisko CP(s32[0], s[0], tv_usec); 1240153247Sambrisko CP(s32[1], s[1], tv_sec); 1241153247Sambrisko CP(s32[1], s[1], tv_usec); 1242153247Sambrisko sp = s; 1243153247Sambrisko } else 1244153247Sambrisko sp = NULL; 1245153247Sambrisko return (kern_futimes(td, uap->fd, sp, UIO_SYSSPACE)); 1246153247Sambrisko} 1247153247Sambrisko 1248153247Sambrisko 1249153247Sambriskoint 1250119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) 1251100384Speter{ 1252144450Sjhb struct timeval32 tv32; 1253144450Sjhb struct timeval delta, olddelta, *deltap; 1254100384Speter int error; 1255100384Speter 1256144450Sjhb if (uap->delta) { 1257144450Sjhb error = copyin(uap->delta, &tv32, sizeof(tv32)); 1258100384Speter if (error) 1259100384Speter return (error); 1260144450Sjhb CP(tv32, delta, tv_sec); 1261144450Sjhb CP(tv32, delta, tv_usec); 1262144450Sjhb deltap = δ 1263144450Sjhb } else 1264144450Sjhb deltap = NULL; 1265144450Sjhb error = kern_adjtime(td, deltap, &olddelta); 1266144450Sjhb if (uap->olddelta && error == 0) { 1267144450Sjhb CP(olddelta, tv32, tv_sec); 1268144450Sjhb CP(olddelta, tv32, tv_usec); 1269144450Sjhb error = copyout(&tv32, uap->olddelta, sizeof(tv32)); 1270100384Speter } 1271100384Speter return (error); 1272100384Speter} 1273100384Speter 1274128597Smarcel#ifdef COMPAT_FREEBSD4 1275100384Speterint 1276128260Speterfreebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap) 1277100384Speter{ 1278142059Sjhb struct statfs32 s32; 1279142059Sjhb struct statfs s; 1280100384Speter int error; 1281100384Speter 1282142059Sjhb error = kern_statfs(td, uap->path, UIO_USERSPACE, &s); 1283100384Speter if (error) 1284100384Speter return (error); 1285142059Sjhb copy_statfs(&s, &s32); 1286142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 1287100384Speter} 1288128597Smarcel#endif 1289100384Speter 1290128597Smarcel#ifdef COMPAT_FREEBSD4 1291100384Speterint 1292128260Speterfreebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap) 1293100384Speter{ 1294142059Sjhb struct statfs32 s32; 1295142059Sjhb struct statfs s; 1296100384Speter int error; 1297100384Speter 1298142059Sjhb error = kern_fstatfs(td, uap->fd, &s); 1299100384Speter if (error) 1300100384Speter return (error); 1301142059Sjhb copy_statfs(&s, &s32); 1302142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 1303100384Speter} 1304128597Smarcel#endif 1305100384Speter 1306128597Smarcel#ifdef COMPAT_FREEBSD4 1307100384Speterint 1308128260Speterfreebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap) 1309128260Speter{ 1310142059Sjhb struct statfs32 s32; 1311142059Sjhb struct statfs s; 1312142059Sjhb fhandle_t fh; 1313128260Speter int error; 1314128260Speter 1315142059Sjhb if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0) 1316142059Sjhb return (error); 1317142059Sjhb error = kern_fhstatfs(td, fh, &s); 1318128260Speter if (error) 1319128260Speter return (error); 1320142059Sjhb copy_statfs(&s, &s32); 1321142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 1322128260Speter} 1323128597Smarcel#endif 1324128260Speter 1325128260Speterint 1326119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap) 1327100384Speter{ 1328100384Speter /* 1329100384Speter * Vector through to semsys if it is loaded. 1330100384Speter */ 1331150883Sjhb return sysent[SYS_semsys].sy_call(td, uap); 1332100384Speter} 1333100384Speter 1334100384Speterint 1335119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap) 1336100384Speter{ 1337100384Speter /* 1338100384Speter * Vector through to msgsys if it is loaded. 1339100384Speter */ 1340150883Sjhb return sysent[SYS_msgsys].sy_call(td, uap); 1341100384Speter} 1342100384Speter 1343100384Speterint 1344119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap) 1345100384Speter{ 1346157285Sps 1347157285Sps switch (uap->which) { 1348157285Sps case 0: { /* shmat */ 1349157285Sps struct shmat_args ap; 1350157285Sps 1351157285Sps ap.shmid = uap->a2; 1352157285Sps ap.shmaddr = PTRIN(uap->a3); 1353157285Sps ap.shmflg = uap->a4; 1354157285Sps return (sysent[SYS_shmat].sy_call(td, &ap)); 1355157285Sps } 1356157285Sps case 2: { /* shmdt */ 1357157285Sps struct shmdt_args ap; 1358157285Sps 1359157285Sps ap.shmaddr = PTRIN(uap->a2); 1360157285Sps return (sysent[SYS_shmdt].sy_call(td, &ap)); 1361157285Sps } 1362157285Sps case 3: { /* shmget */ 1363157285Sps struct shmget_args ap; 1364157285Sps 1365157285Sps ap.key = uap->a2; 1366157285Sps ap.size = uap->a3; 1367157285Sps ap.shmflg = uap->a4; 1368157285Sps return (sysent[SYS_shmget].sy_call(td, &ap)); 1369157285Sps } 1370157285Sps case 4: { /* shmctl */ 1371157285Sps struct freebsd32_shmctl_args ap; 1372157285Sps 1373157285Sps ap.shmid = uap->a2; 1374157285Sps ap.cmd = uap->a3; 1375157285Sps ap.buf = PTRIN(uap->a4); 1376157285Sps return (freebsd32_shmctl(td, &ap)); 1377157285Sps } 1378157285Sps case 1: /* oshmctl */ 1379157285Sps default: 1380157285Sps return (EINVAL); 1381157285Sps } 1382100384Speter} 1383100384Speter 1384157285Spsstruct ipc_perm32 { 1385157285Sps uint16_t cuid; 1386157285Sps uint16_t cgid; 1387157285Sps uint16_t uid; 1388157285Sps uint16_t gid; 1389157285Sps uint16_t mode; 1390157285Sps uint16_t seq; 1391157285Sps uint32_t key; 1392157285Sps}; 1393157285Spsstruct shmid_ds32 { 1394157285Sps struct ipc_perm32 shm_perm; 1395157285Sps int32_t shm_segsz; 1396157285Sps int32_t shm_lpid; 1397157285Sps int32_t shm_cpid; 1398157285Sps int16_t shm_nattch; 1399157285Sps int32_t shm_atime; 1400157285Sps int32_t shm_dtime; 1401157285Sps int32_t shm_ctime; 1402157285Sps uint32_t shm_internal; 1403157285Sps}; 1404157285Spsstruct shm_info32 { 1405157285Sps int32_t used_ids; 1406157285Sps uint32_t shm_tot; 1407157285Sps uint32_t shm_rss; 1408157285Sps uint32_t shm_swp; 1409157285Sps uint32_t swap_attempts; 1410157285Sps uint32_t swap_successes; 1411157285Sps}; 1412157285Spsstruct shminfo32 { 1413157285Sps uint32_t shmmax; 1414157285Sps uint32_t shmmin; 1415157285Sps uint32_t shmmni; 1416157285Sps uint32_t shmseg; 1417157285Sps uint32_t shmall; 1418157285Sps}; 1419157285Sps 1420100384Speterint 1421157285Spsfreebsd32_shmctl(struct thread *td, struct freebsd32_shmctl_args *uap) 1422157285Sps{ 1423157285Sps int error = 0; 1424157285Sps union { 1425157285Sps struct shmid_ds shmid_ds; 1426157285Sps struct shm_info shm_info; 1427157285Sps struct shminfo shminfo; 1428157285Sps } u; 1429157285Sps union { 1430157285Sps struct shmid_ds32 shmid_ds32; 1431157285Sps struct shm_info32 shm_info32; 1432157285Sps struct shminfo32 shminfo32; 1433157285Sps } u32; 1434157285Sps size_t sz; 1435157285Sps 1436157285Sps if (uap->cmd == IPC_SET) { 1437157285Sps if ((error = copyin(uap->buf, &u32.shmid_ds32, 1438157285Sps sizeof(u32.shmid_ds32)))) 1439157285Sps goto done; 1440157285Sps CP(u32.shmid_ds32, u.shmid_ds, shm_perm.cuid); 1441157285Sps CP(u32.shmid_ds32, u.shmid_ds, shm_perm.cgid); 1442157285Sps CP(u32.shmid_ds32, u.shmid_ds, shm_perm.uid); 1443157285Sps CP(u32.shmid_ds32, u.shmid_ds, shm_perm.gid); 1444157285Sps CP(u32.shmid_ds32, u.shmid_ds, shm_perm.mode); 1445157285Sps CP(u32.shmid_ds32, u.shmid_ds, shm_perm.seq); 1446157285Sps CP(u32.shmid_ds32, u.shmid_ds, shm_perm.key); 1447157285Sps CP(u32.shmid_ds32, u.shmid_ds, shm_segsz); 1448157285Sps CP(u32.shmid_ds32, u.shmid_ds, shm_lpid); 1449157285Sps CP(u32.shmid_ds32, u.shmid_ds, shm_cpid); 1450157285Sps CP(u32.shmid_ds32, u.shmid_ds, shm_nattch); 1451157285Sps CP(u32.shmid_ds32, u.shmid_ds, shm_atime); 1452157285Sps CP(u32.shmid_ds32, u.shmid_ds, shm_dtime); 1453157285Sps CP(u32.shmid_ds32, u.shmid_ds, shm_ctime); 1454157285Sps PTRIN_CP(u32.shmid_ds32, u.shmid_ds, shm_internal); 1455157285Sps } 1456157285Sps 1457157285Sps error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz); 1458157285Sps if (error) 1459157285Sps goto done; 1460157285Sps 1461157285Sps /* Cases in which we need to copyout */ 1462157285Sps switch (uap->cmd) { 1463157285Sps case IPC_INFO: 1464157285Sps CP(u.shminfo, u32.shminfo32, shmmax); 1465157285Sps CP(u.shminfo, u32.shminfo32, shmmin); 1466157285Sps CP(u.shminfo, u32.shminfo32, shmmni); 1467157285Sps CP(u.shminfo, u32.shminfo32, shmseg); 1468157285Sps CP(u.shminfo, u32.shminfo32, shmall); 1469157285Sps error = copyout(&u32.shminfo32, uap->buf, 1470157285Sps sizeof(u32.shminfo32)); 1471157285Sps break; 1472157285Sps case SHM_INFO: 1473157285Sps CP(u.shm_info, u32.shm_info32, used_ids); 1474157285Sps CP(u.shm_info, u32.shm_info32, shm_rss); 1475157285Sps CP(u.shm_info, u32.shm_info32, shm_tot); 1476157285Sps CP(u.shm_info, u32.shm_info32, shm_swp); 1477157285Sps CP(u.shm_info, u32.shm_info32, swap_attempts); 1478157285Sps CP(u.shm_info, u32.shm_info32, swap_successes); 1479157285Sps error = copyout(&u32.shm_info32, uap->buf, 1480157285Sps sizeof(u32.shm_info32)); 1481157285Sps break; 1482157285Sps case SHM_STAT: 1483157285Sps case IPC_STAT: 1484157285Sps CP(u.shmid_ds, u32.shmid_ds32, shm_perm.cuid); 1485157285Sps CP(u.shmid_ds, u32.shmid_ds32, shm_perm.cgid); 1486157285Sps CP(u.shmid_ds, u32.shmid_ds32, shm_perm.uid); 1487157285Sps CP(u.shmid_ds, u32.shmid_ds32, shm_perm.gid); 1488157285Sps CP(u.shmid_ds, u32.shmid_ds32, shm_perm.mode); 1489157285Sps CP(u.shmid_ds, u32.shmid_ds32, shm_perm.seq); 1490157285Sps CP(u.shmid_ds, u32.shmid_ds32, shm_perm.key); 1491157285Sps CP(u.shmid_ds, u32.shmid_ds32, shm_segsz); 1492157285Sps CP(u.shmid_ds, u32.shmid_ds32, shm_lpid); 1493157285Sps CP(u.shmid_ds, u32.shmid_ds32, shm_cpid); 1494157285Sps CP(u.shmid_ds, u32.shmid_ds32, shm_nattch); 1495157285Sps CP(u.shmid_ds, u32.shmid_ds32, shm_atime); 1496157285Sps CP(u.shmid_ds, u32.shmid_ds32, shm_dtime); 1497157285Sps CP(u.shmid_ds, u32.shmid_ds32, shm_ctime); 1498157285Sps PTROUT_CP(u.shmid_ds, u32.shmid_ds32, shm_internal); 1499157285Sps error = copyout(&u32.shmid_ds32, uap->buf, 1500157285Sps sizeof(u32.shmid_ds32)); 1501157285Sps break; 1502157285Sps } 1503157285Sps 1504157285Spsdone: 1505157285Sps if (error) { 1506157285Sps /* Invalidate the return value */ 1507157285Sps td->td_retval[0] = -1; 1508157285Sps } 1509157285Sps return (error); 1510157285Sps} 1511157285Sps 1512157285Spsint 1513119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) 1514100384Speter{ 1515100384Speter struct pread_args ap; 1516100384Speter 1517107849Salfred ap.fd = uap->fd; 1518107849Salfred ap.buf = uap->buf; 1519107849Salfred ap.nbyte = uap->nbyte; 1520119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1521100384Speter return (pread(td, &ap)); 1522100384Speter} 1523100384Speter 1524100384Speterint 1525119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap) 1526100384Speter{ 1527100384Speter struct pwrite_args ap; 1528100384Speter 1529107849Salfred ap.fd = uap->fd; 1530107849Salfred ap.buf = uap->buf; 1531107849Salfred ap.nbyte = uap->nbyte; 1532119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1533100384Speter return (pwrite(td, &ap)); 1534100384Speter} 1535100384Speter 1536100384Speterint 1537119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap) 1538100384Speter{ 1539100384Speter int error; 1540100384Speter struct lseek_args ap; 1541100384Speter off_t pos; 1542100384Speter 1543107849Salfred ap.fd = uap->fd; 1544119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1545107849Salfred ap.whence = uap->whence; 1546100384Speter error = lseek(td, &ap); 1547100384Speter /* Expand the quad return into two parts for eax and edx */ 1548100384Speter pos = *(off_t *)(td->td_retval); 1549100384Speter td->td_retval[0] = pos & 0xffffffff; /* %eax */ 1550100384Speter td->td_retval[1] = pos >> 32; /* %edx */ 1551100384Speter return error; 1552100384Speter} 1553100384Speter 1554100384Speterint 1555119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap) 1556100384Speter{ 1557100384Speter struct truncate_args ap; 1558100384Speter 1559107849Salfred ap.path = uap->path; 1560119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1561100384Speter return (truncate(td, &ap)); 1562100384Speter} 1563100384Speter 1564100384Speterint 1565119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) 1566100384Speter{ 1567100384Speter struct ftruncate_args ap; 1568100384Speter 1569107849Salfred ap.fd = uap->fd; 1570119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1571100384Speter return (ftruncate(td, &ap)); 1572100384Speter} 1573100384Speter 1574156114Spsstruct sf_hdtr32 { 1575156114Sps uint32_t headers; 1576156114Sps int hdr_cnt; 1577156114Sps uint32_t trailers; 1578156114Sps int trl_cnt; 1579156114Sps}; 1580156114Sps 1581156114Spsstatic int 1582156114Spsfreebsd32_do_sendfile(struct thread *td, 1583156114Sps struct freebsd32_sendfile_args *uap, int compat) 1584104738Speter{ 1585156114Sps struct sendfile_args ap; 1586156114Sps struct sf_hdtr32 hdtr32; 1587156114Sps struct sf_hdtr hdtr; 1588156114Sps struct uio *hdr_uio, *trl_uio; 1589156114Sps struct iovec32 *iov32; 1590156114Sps int error; 1591104738Speter 1592156114Sps hdr_uio = trl_uio = NULL; 1593156114Sps 1594107849Salfred ap.fd = uap->fd; 1595107849Salfred ap.s = uap->s; 1596119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1597156114Sps ap.nbytes = uap->nbytes; 1598156114Sps ap.hdtr = (struct sf_hdtr *)uap->hdtr; /* XXX not used */ 1599156114Sps ap.sbytes = uap->sbytes; 1600107849Salfred ap.flags = uap->flags; 1601156114Sps 1602156114Sps if (uap->hdtr != NULL) { 1603156114Sps error = copyin(uap->hdtr, &hdtr32, sizeof(hdtr32)); 1604156114Sps if (error) 1605156114Sps goto out; 1606156114Sps PTRIN_CP(hdtr32, hdtr, headers); 1607156114Sps CP(hdtr32, hdtr, hdr_cnt); 1608156114Sps PTRIN_CP(hdtr32, hdtr, trailers); 1609156114Sps CP(hdtr32, hdtr, trl_cnt); 1610156114Sps 1611156114Sps if (hdtr.headers != NULL) { 1612160246Sjhb iov32 = PTRIN(hdtr32.headers); 1613156114Sps error = freebsd32_copyinuio(iov32, 1614156114Sps hdtr32.hdr_cnt, &hdr_uio); 1615156114Sps if (error) 1616156114Sps goto out; 1617156114Sps } 1618156114Sps if (hdtr.trailers != NULL) { 1619160246Sjhb iov32 = PTRIN(hdtr32.trailers); 1620156114Sps error = freebsd32_copyinuio(iov32, 1621156114Sps hdtr32.trl_cnt, &trl_uio); 1622156114Sps if (error) 1623156114Sps goto out; 1624156114Sps } 1625156114Sps } 1626156114Sps 1627156114Sps error = kern_sendfile(td, &ap, hdr_uio, trl_uio, compat); 1628156114Spsout: 1629156114Sps if (hdr_uio) 1630156114Sps free(hdr_uio, M_IOV); 1631156114Sps if (trl_uio) 1632156114Sps free(trl_uio, M_IOV); 1633156114Sps return (error); 1634104738Speter} 1635156114Sps 1636156114Sps#ifdef COMPAT_FREEBSD4 1637156114Spsint 1638156114Spsfreebsd4_freebsd32_sendfile(struct thread *td, 1639156114Sps struct freebsd4_freebsd32_sendfile_args *uap) 1640156114Sps{ 1641156114Sps return (freebsd32_do_sendfile(td, 1642156114Sps (struct freebsd32_sendfile_args *)uap, 1)); 1643156114Sps} 1644104738Speter#endif 1645104738Speter 1646104738Speterint 1647119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap) 1648100384Speter{ 1649100384Speter 1650156114Sps return (freebsd32_do_sendfile(td, uap, 0)); 1651100384Speter} 1652100384Speter 1653100384Speterstruct stat32 { 1654130640Sphk dev_t st_dev; 1655100384Speter ino_t st_ino; 1656100384Speter mode_t st_mode; 1657100384Speter nlink_t st_nlink; 1658100384Speter uid_t st_uid; 1659100384Speter gid_t st_gid; 1660130640Sphk dev_t st_rdev; 1661100384Speter struct timespec32 st_atimespec; 1662100384Speter struct timespec32 st_mtimespec; 1663100384Speter struct timespec32 st_ctimespec; 1664100384Speter off_t st_size; 1665100384Speter int64_t st_blocks; 1666100384Speter u_int32_t st_blksize; 1667100384Speter u_int32_t st_flags; 1668100384Speter u_int32_t st_gen; 1669121719Speter struct timespec32 st_birthtimespec; 1670121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1671121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1672100384Speter}; 1673100384Speter 1674121719Speter 1675121719SpeterCTASSERT(sizeof(struct stat32) == 96); 1676121719Speter 1677100384Speterstatic void 1678100384Spetercopy_stat( struct stat *in, struct stat32 *out) 1679100384Speter{ 1680100384Speter CP(*in, *out, st_dev); 1681100384Speter CP(*in, *out, st_ino); 1682100384Speter CP(*in, *out, st_mode); 1683100384Speter CP(*in, *out, st_nlink); 1684100384Speter CP(*in, *out, st_uid); 1685100384Speter CP(*in, *out, st_gid); 1686100384Speter CP(*in, *out, st_rdev); 1687100384Speter TS_CP(*in, *out, st_atimespec); 1688100384Speter TS_CP(*in, *out, st_mtimespec); 1689100384Speter TS_CP(*in, *out, st_ctimespec); 1690100384Speter CP(*in, *out, st_size); 1691100384Speter CP(*in, *out, st_blocks); 1692100384Speter CP(*in, *out, st_blksize); 1693100384Speter CP(*in, *out, st_flags); 1694100384Speter CP(*in, *out, st_gen); 1695100384Speter} 1696100384Speter 1697100384Speterint 1698119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap) 1699100384Speter{ 1700123746Speter struct stat sb; 1701123746Speter struct stat32 sb32; 1702100384Speter int error; 1703100384Speter 1704142059Sjhb error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 1705100384Speter if (error) 1706100384Speter return (error); 1707123746Speter copy_stat(&sb, &sb32); 1708123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1709100384Speter return (error); 1710100384Speter} 1711100384Speter 1712100384Speterint 1713119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap) 1714100384Speter{ 1715123746Speter struct stat ub; 1716123746Speter struct stat32 ub32; 1717100384Speter int error; 1718100384Speter 1719142059Sjhb error = kern_fstat(td, uap->fd, &ub); 1720100384Speter if (error) 1721100384Speter return (error); 1722123746Speter copy_stat(&ub, &ub32); 1723123746Speter error = copyout(&ub32, uap->ub, sizeof(ub32)); 1724100384Speter return (error); 1725100384Speter} 1726100384Speter 1727100384Speterint 1728119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap) 1729100384Speter{ 1730123746Speter struct stat sb; 1731123746Speter struct stat32 sb32; 1732142059Sjhb int error; 1733100384Speter 1734142059Sjhb error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 1735100384Speter if (error) 1736100384Speter return (error); 1737123746Speter copy_stat(&sb, &sb32); 1738123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1739100384Speter return (error); 1740100384Speter} 1741100384Speter 1742100384Speter/* 1743100384Speter * MPSAFE 1744100384Speter */ 1745100384Speterint 1746119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap) 1747100384Speter{ 1748100384Speter int error, name[CTL_MAXNAME]; 1749100384Speter size_t j, oldlen; 1750100384Speter 1751100384Speter if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1752100384Speter return (EINVAL); 1753136404Speter error = copyin(uap->name, name, uap->namelen * sizeof(int)); 1754100384Speter if (error) 1755100384Speter return (error); 1756100384Speter mtx_lock(&Giant); 1757100384Speter if (uap->oldlenp) 1758100384Speter oldlen = fuword32(uap->oldlenp); 1759100384Speter else 1760100384Speter oldlen = 0; 1761100384Speter error = userland_sysctl(td, name, uap->namelen, 1762100384Speter uap->old, &oldlen, 1, 1763136404Speter uap->new, uap->newlen, &j, SCTL_MASK32); 1764100384Speter if (error && error != ENOMEM) 1765100384Speter goto done2; 1766136404Speter if (uap->oldlenp) 1767100384Speter suword32(uap->oldlenp, j); 1768100384Speterdone2: 1769100384Speter mtx_unlock(&Giant); 1770100384Speter return (error); 1771100384Speter} 1772100384Speter 1773100384Speterstruct sigaction32 { 1774100384Speter u_int32_t sa_u; 1775100384Speter int sa_flags; 1776100384Speter sigset_t sa_mask; 1777100384Speter}; 1778100384Speter 1779121719SpeterCTASSERT(sizeof(struct sigaction32) == 24); 1780121719Speter 1781100384Speterint 1782119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap) 1783100384Speter{ 1784113859Sjhb struct sigaction32 s32; 1785113859Sjhb struct sigaction sa, osa, *sap; 1786100384Speter int error; 1787100384Speter 1788113859Sjhb if (uap->act) { 1789113859Sjhb error = copyin(uap->act, &s32, sizeof(s32)); 1790100384Speter if (error) 1791100384Speter return (error); 1792113859Sjhb sa.sa_handler = PTRIN(s32.sa_u); 1793113859Sjhb CP(s32, sa, sa_flags); 1794113859Sjhb CP(s32, sa, sa_mask); 1795113859Sjhb sap = &sa; 1796113859Sjhb } else 1797113859Sjhb sap = NULL; 1798113859Sjhb error = kern_sigaction(td, uap->sig, sap, &osa, 0); 1799146583Sps if (error == 0 && uap->oact != NULL) { 1800113859Sjhb s32.sa_u = PTROUT(osa.sa_handler); 1801113859Sjhb CP(osa, s32, sa_flags); 1802113859Sjhb CP(osa, s32, sa_mask); 1803113859Sjhb error = copyout(&s32, uap->oact, sizeof(s32)); 1804100384Speter } 1805100384Speter return (error); 1806100384Speter} 1807100384Speter 1808114987Speter#ifdef COMPAT_FREEBSD4 1809114987Speterint 1810119333Speterfreebsd4_freebsd32_sigaction(struct thread *td, 1811119333Speter struct freebsd4_freebsd32_sigaction_args *uap) 1812114987Speter{ 1813114987Speter struct sigaction32 s32; 1814114987Speter struct sigaction sa, osa, *sap; 1815114987Speter int error; 1816114987Speter 1817114987Speter if (uap->act) { 1818114987Speter error = copyin(uap->act, &s32, sizeof(s32)); 1819114987Speter if (error) 1820114987Speter return (error); 1821114987Speter sa.sa_handler = PTRIN(s32.sa_u); 1822114987Speter CP(s32, sa, sa_flags); 1823114987Speter CP(s32, sa, sa_mask); 1824114987Speter sap = &sa; 1825114987Speter } else 1826114987Speter sap = NULL; 1827114987Speter error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4); 1828146583Sps if (error == 0 && uap->oact != NULL) { 1829114987Speter s32.sa_u = PTROUT(osa.sa_handler); 1830114987Speter CP(osa, s32, sa_flags); 1831114987Speter CP(osa, s32, sa_mask); 1832114987Speter error = copyout(&s32, uap->oact, sizeof(s32)); 1833114987Speter } 1834114987Speter return (error); 1835114987Speter} 1836114987Speter#endif 1837114987Speter 1838151582Sps#ifdef COMPAT_43 1839151720Speterstruct osigaction32 { 1840151582Sps u_int32_t sa_u; 1841151582Sps osigset_t sa_mask; 1842151582Sps int sa_flags; 1843151582Sps}; 1844151582Sps 1845151582Sps#define ONSIG 32 1846151582Sps 1847140481Spsint 1848151720Speterofreebsd32_sigaction(struct thread *td, 1849151720Speter struct ofreebsd32_sigaction_args *uap) 1850151582Sps{ 1851151720Speter struct osigaction32 s32; 1852151582Sps struct sigaction sa, osa, *sap; 1853151582Sps int error; 1854151582Sps 1855151582Sps if (uap->signum <= 0 || uap->signum >= ONSIG) 1856151582Sps return (EINVAL); 1857151582Sps 1858151582Sps if (uap->nsa) { 1859151582Sps error = copyin(uap->nsa, &s32, sizeof(s32)); 1860151582Sps if (error) 1861151582Sps return (error); 1862151582Sps sa.sa_handler = PTRIN(s32.sa_u); 1863151582Sps CP(s32, sa, sa_flags); 1864151582Sps OSIG2SIG(s32.sa_mask, sa.sa_mask); 1865151582Sps sap = &sa; 1866151582Sps } else 1867151582Sps sap = NULL; 1868151582Sps error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET); 1869151582Sps if (error == 0 && uap->osa != NULL) { 1870151582Sps s32.sa_u = PTROUT(osa.sa_handler); 1871151582Sps CP(osa, s32, sa_flags); 1872151582Sps SIG2OSIG(osa.sa_mask, s32.sa_mask); 1873151582Sps error = copyout(&s32, uap->osa, sizeof(s32)); 1874151582Sps } 1875151582Sps return (error); 1876151582Sps} 1877151582Sps 1878151582Spsint 1879151720Speterofreebsd32_sigprocmask(struct thread *td, 1880151720Speter struct ofreebsd32_sigprocmask_args *uap) 1881151582Sps{ 1882151582Sps sigset_t set, oset; 1883151582Sps int error; 1884151582Sps 1885151582Sps OSIG2SIG(uap->mask, set); 1886151582Sps error = kern_sigprocmask(td, uap->how, &set, &oset, 1); 1887151582Sps SIG2OSIG(oset, td->td_retval[0]); 1888151582Sps return (error); 1889151582Sps} 1890151582Sps 1891151582Spsint 1892151720Speterofreebsd32_sigpending(struct thread *td, 1893151720Speter struct ofreebsd32_sigpending_args *uap) 1894151582Sps{ 1895151582Sps struct proc *p = td->td_proc; 1896151582Sps sigset_t siglist; 1897151582Sps 1898151582Sps PROC_LOCK(p); 1899151582Sps siglist = p->p_siglist; 1900151582Sps SIGSETOR(siglist, td->td_siglist); 1901151582Sps PROC_UNLOCK(p); 1902151582Sps SIG2OSIG(siglist, td->td_retval[0]); 1903151582Sps return (0); 1904151582Sps} 1905151582Sps 1906151582Spsstruct sigvec32 { 1907151582Sps u_int32_t sv_handler; 1908151582Sps int sv_mask; 1909151582Sps int sv_flags; 1910151582Sps}; 1911151582Sps 1912151582Spsint 1913151720Speterofreebsd32_sigvec(struct thread *td, 1914151720Speter struct ofreebsd32_sigvec_args *uap) 1915151582Sps{ 1916151582Sps struct sigvec32 vec; 1917151582Sps struct sigaction sa, osa, *sap; 1918151582Sps int error; 1919151582Sps 1920151582Sps if (uap->signum <= 0 || uap->signum >= ONSIG) 1921151582Sps return (EINVAL); 1922151582Sps 1923151582Sps if (uap->nsv) { 1924151582Sps error = copyin(uap->nsv, &vec, sizeof(vec)); 1925151582Sps if (error) 1926151582Sps return (error); 1927151582Sps sa.sa_handler = PTRIN(vec.sv_handler); 1928151582Sps OSIG2SIG(vec.sv_mask, sa.sa_mask); 1929151582Sps sa.sa_flags = vec.sv_flags; 1930151582Sps sa.sa_flags ^= SA_RESTART; 1931151582Sps sap = &sa; 1932151582Sps } else 1933151582Sps sap = NULL; 1934151582Sps error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET); 1935151582Sps if (error == 0 && uap->osv != NULL) { 1936151582Sps vec.sv_handler = PTROUT(osa.sa_handler); 1937151582Sps SIG2OSIG(osa.sa_mask, vec.sv_mask); 1938151582Sps vec.sv_flags = osa.sa_flags; 1939151582Sps vec.sv_flags &= ~SA_NOCLDWAIT; 1940151582Sps vec.sv_flags ^= SA_RESTART; 1941151582Sps error = copyout(&vec, uap->osv, sizeof(vec)); 1942151582Sps } 1943151582Sps return (error); 1944151582Sps} 1945151582Sps 1946151582Spsint 1947151720Speterofreebsd32_sigblock(struct thread *td, 1948151720Speter struct ofreebsd32_sigblock_args *uap) 1949151582Sps{ 1950151582Sps struct proc *p = td->td_proc; 1951151582Sps sigset_t set; 1952151582Sps 1953151582Sps OSIG2SIG(uap->mask, set); 1954151582Sps SIG_CANTMASK(set); 1955151582Sps PROC_LOCK(p); 1956151582Sps SIG2OSIG(td->td_sigmask, td->td_retval[0]); 1957151582Sps SIGSETOR(td->td_sigmask, set); 1958151582Sps PROC_UNLOCK(p); 1959151582Sps return (0); 1960151582Sps} 1961151582Sps 1962151582Spsint 1963151720Speterofreebsd32_sigsetmask(struct thread *td, 1964151720Speter struct ofreebsd32_sigsetmask_args *uap) 1965151582Sps{ 1966151582Sps struct proc *p = td->td_proc; 1967151582Sps sigset_t set; 1968151582Sps 1969151582Sps OSIG2SIG(uap->mask, set); 1970151582Sps SIG_CANTMASK(set); 1971151582Sps PROC_LOCK(p); 1972151582Sps SIG2OSIG(td->td_sigmask, td->td_retval[0]); 1973151582Sps SIGSETLO(td->td_sigmask, set); 1974151582Sps signotify(td); 1975151582Sps PROC_UNLOCK(p); 1976151582Sps return (0); 1977151582Sps} 1978151582Sps 1979151582Spsint 1980151720Speterofreebsd32_sigsuspend(struct thread *td, 1981151720Speter struct ofreebsd32_sigsuspend_args *uap) 1982151582Sps{ 1983151582Sps struct proc *p = td->td_proc; 1984151582Sps sigset_t mask; 1985151582Sps 1986151582Sps PROC_LOCK(p); 1987151582Sps td->td_oldsigmask = td->td_sigmask; 1988151582Sps td->td_pflags |= TDP_OLDMASK; 1989151582Sps OSIG2SIG(uap->mask, mask); 1990151582Sps SIG_CANTMASK(mask); 1991151582Sps SIGSETLO(td->td_sigmask, mask); 1992151582Sps signotify(td); 1993151582Sps while (msleep(&p->p_sigacts, &p->p_mtx, PPAUSE|PCATCH, "opause", 0) == 0) 1994151582Sps /* void */; 1995151582Sps PROC_UNLOCK(p); 1996151582Sps /* always return EINTR rather than ERESTART... */ 1997151582Sps return (EINTR); 1998151582Sps} 1999151582Sps 2000151582Spsstruct sigstack32 { 2001151582Sps u_int32_t ss_sp; 2002151582Sps int ss_onstack; 2003151582Sps}; 2004151582Sps 2005151582Spsint 2006151720Speterofreebsd32_sigstack(struct thread *td, 2007151720Speter struct ofreebsd32_sigstack_args *uap) 2008151582Sps{ 2009151582Sps struct sigstack32 s32; 2010151582Sps struct sigstack nss, oss; 2011151582Sps int error = 0; 2012151582Sps 2013151582Sps if (uap->nss != NULL) { 2014151582Sps error = copyin(uap->nss, &s32, sizeof(s32)); 2015151582Sps if (error) 2016151582Sps return (error); 2017151582Sps nss.ss_sp = PTRIN(s32.ss_sp); 2018151582Sps CP(s32, nss, ss_onstack); 2019151582Sps } 2020151582Sps oss.ss_sp = td->td_sigstk.ss_sp; 2021151582Sps oss.ss_onstack = sigonstack(cpu_getstack(td)); 2022151582Sps if (uap->nss != NULL) { 2023151582Sps td->td_sigstk.ss_sp = nss.ss_sp; 2024151582Sps td->td_sigstk.ss_size = 0; 2025151582Sps td->td_sigstk.ss_flags |= nss.ss_onstack & SS_ONSTACK; 2026151582Sps td->td_pflags |= TDP_ALTSTACK; 2027151582Sps } 2028151582Sps if (uap->oss != NULL) { 2029151582Sps s32.ss_sp = PTROUT(oss.ss_sp); 2030151582Sps CP(oss, s32, ss_onstack); 2031151582Sps error = copyout(&s32, uap->oss, sizeof(s32)); 2032151582Sps } 2033151582Sps return (error); 2034151582Sps} 2035151582Sps#endif 2036151582Sps 2037151582Spsint 2038140481Spsfreebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap) 2039140481Sps{ 2040140481Sps struct timespec32 rmt32, rqt32; 2041140481Sps struct timespec rmt, rqt; 2042140481Sps int error; 2043140481Sps 2044151355Sps error = copyin(uap->rqtp, &rqt32, sizeof(rqt32)); 2045140481Sps if (error) 2046140481Sps return (error); 2047140481Sps 2048140481Sps CP(rqt32, rqt, tv_sec); 2049140481Sps CP(rqt32, rqt, tv_nsec); 2050140481Sps 2051140481Sps if (uap->rmtp && 2052140481Sps !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE)) 2053140481Sps return (EFAULT); 2054140481Sps error = kern_nanosleep(td, &rqt, &rmt); 2055140481Sps if (error && uap->rmtp) { 2056140481Sps int error2; 2057140481Sps 2058140481Sps CP(rmt, rmt32, tv_sec); 2059140481Sps CP(rmt, rmt32, tv_nsec); 2060140481Sps 2061151355Sps error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt32)); 2062140481Sps if (error2) 2063140481Sps error = error2; 2064140481Sps } 2065140481Sps return (error); 2066140481Sps} 2067140481Sps 2068151357Spsint 2069151357Spsfreebsd32_clock_gettime(struct thread *td, 2070151357Sps struct freebsd32_clock_gettime_args *uap) 2071151357Sps{ 2072151357Sps struct timespec ats; 2073151357Sps struct timespec32 ats32; 2074151357Sps int error; 2075151357Sps 2076151357Sps error = kern_clock_gettime(td, uap->clock_id, &ats); 2077151357Sps if (error == 0) { 2078151357Sps CP(ats, ats32, tv_sec); 2079151357Sps CP(ats, ats32, tv_nsec); 2080151357Sps error = copyout(&ats32, uap->tp, sizeof(ats32)); 2081151357Sps } 2082151357Sps return (error); 2083151357Sps} 2084151357Sps 2085151357Spsint 2086151357Spsfreebsd32_clock_settime(struct thread *td, 2087151357Sps struct freebsd32_clock_settime_args *uap) 2088151357Sps{ 2089151357Sps struct timespec ats; 2090151357Sps struct timespec32 ats32; 2091151357Sps int error; 2092151357Sps 2093151357Sps error = copyin(uap->tp, &ats32, sizeof(ats32)); 2094151357Sps if (error) 2095151357Sps return (error); 2096151357Sps CP(ats32, ats, tv_sec); 2097151357Sps CP(ats32, ats, tv_nsec); 2098151357Sps 2099151357Sps return (kern_clock_settime(td, uap->clock_id, &ats)); 2100151357Sps} 2101151357Sps 2102151357Spsint 2103151357Spsfreebsd32_clock_getres(struct thread *td, 2104151357Sps struct freebsd32_clock_getres_args *uap) 2105151357Sps{ 2106151357Sps struct timespec ts; 2107151357Sps struct timespec32 ts32; 2108151357Sps int error; 2109151357Sps 2110151357Sps if (uap->tp == NULL) 2111151357Sps return (0); 2112151357Sps error = kern_clock_getres(td, uap->clock_id, &ts); 2113151357Sps if (error == 0) { 2114151357Sps CP(ts, ts32, tv_sec); 2115151357Sps CP(ts, ts32, tv_nsec); 2116151357Sps error = copyout(&ts32, uap->tp, sizeof(ts32)); 2117151357Sps } 2118151357Sps return (error); 2119151357Sps} 2120151357Sps 2121100384Speter#if 0 2122100384Speter 2123100384Speterint 2124119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) 2125100384Speter{ 2126100384Speter int error; 2127100384Speter struct yyy32 *p32, s32; 2128100384Speter struct yyy *p = NULL, s; 2129100384Speter 2130147654Sjhb if (uap->zzz) { 2131147654Sjhb error = copyin(uap->zzz, &s32, sizeof(s32)); 2132100384Speter if (error) 2133100384Speter return (error); 2134100384Speter /* translate in */ 2135147654Sjhb p = &s; 2136100384Speter } 2137147654Sjhb error = kern_xxx(td, p); 2138100384Speter if (error) 2139100384Speter return (error); 2140147654Sjhb if (uap->zzz) { 2141100384Speter /* translate out */ 2142100384Speter error = copyout(&s32, p32, sizeof(s32)); 2143100384Speter } 2144100384Speter return (error); 2145100384Speter} 2146100384Speter 2147100384Speter#endif 2148