freebsd32_misc.c revision 151720
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 151720 2005-10-26 22:19:51Z peter $"); 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 */ 44100384Speter#include <sys/mman.h> 45100384Speter#include <sys/module.h> 46100384Speter#include <sys/mount.h> 47100384Speter#include <sys/mutex.h> 48100384Speter#include <sys/namei.h> 49100384Speter#include <sys/param.h> 50100384Speter#include <sys/proc.h> 51100384Speter#include <sys/reboot.h> 52100384Speter#include <sys/resource.h> 53100384Speter#include <sys/resourcevar.h> 54100384Speter#include <sys/selinfo.h> 55146950Sps#include <sys/eventvar.h> /* Must come after sys/selinfo.h */ 56100384Speter#include <sys/pipe.h> /* Must come after sys/selinfo.h */ 57100384Speter#include <sys/signal.h> 58100384Speter#include <sys/signalvar.h> 59100384Speter#include <sys/socket.h> 60100384Speter#include <sys/socketvar.h> 61100384Speter#include <sys/stat.h> 62150883Sjhb#include <sys/syscall.h> 63113859Sjhb#include <sys/syscallsubr.h> 64100384Speter#include <sys/sysctl.h> 65100384Speter#include <sys/sysent.h> 66100384Speter#include <sys/sysproto.h> 67100384Speter#include <sys/systm.h> 68100384Speter#include <sys/unistd.h> 69100384Speter#include <sys/vnode.h> 70127140Sjhb#include <sys/wait.h> 71100384Speter 72100384Speter#include <vm/vm.h> 73100384Speter#include <vm/vm_kern.h> 74100384Speter#include <vm/vm_param.h> 75100384Speter#include <vm/pmap.h> 76100384Speter#include <vm/vm_map.h> 77100384Speter#include <vm/vm_object.h> 78100384Speter#include <vm/vm_extern.h> 79100384Speter 80151582Sps#include <machine/cpu.h> 81151582Sps 82119333Speter#include <compat/freebsd32/freebsd32_util.h> 83119333Speter#include <compat/freebsd32/freebsd32.h> 84119333Speter#include <compat/freebsd32/freebsd32_proto.h> 85100384Speter 86121719SpeterCTASSERT(sizeof(struct timeval32) == 8); 87121719SpeterCTASSERT(sizeof(struct timespec32) == 8); 88121719SpeterCTASSERT(sizeof(struct statfs32) == 256); 89121719SpeterCTASSERT(sizeof(struct rusage32) == 72); 90121719Speter 91100384Speterint 92119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) 93100384Speter{ 94127140Sjhb int error, status; 95127140Sjhb struct rusage32 ru32; 96136152Sjhb struct rusage ru, *rup; 97100384Speter 98136152Sjhb if (uap->rusage != NULL) 99136152Sjhb rup = &ru; 100136152Sjhb else 101136152Sjhb rup = NULL; 102136152Sjhb error = kern_wait(td, uap->pid, &status, uap->options, rup); 103100384Speter if (error) 104100384Speter return (error); 105127140Sjhb if (uap->status != NULL) 106127140Sjhb error = copyout(&status, uap->status, sizeof(status)); 107127140Sjhb if (uap->rusage != NULL && error == 0) { 108100384Speter TV_CP(ru, ru32, ru_utime); 109100384Speter TV_CP(ru, ru32, ru_stime); 110100384Speter CP(ru, ru32, ru_maxrss); 111100384Speter CP(ru, ru32, ru_ixrss); 112100384Speter CP(ru, ru32, ru_idrss); 113100384Speter CP(ru, ru32, ru_isrss); 114100384Speter CP(ru, ru32, ru_minflt); 115100384Speter CP(ru, ru32, ru_majflt); 116100384Speter CP(ru, ru32, ru_nswap); 117100384Speter CP(ru, ru32, ru_inblock); 118100384Speter CP(ru, ru32, ru_oublock); 119100384Speter CP(ru, ru32, ru_msgsnd); 120100384Speter CP(ru, ru32, ru_msgrcv); 121100384Speter CP(ru, ru32, ru_nsignals); 122100384Speter CP(ru, ru32, ru_nvcsw); 123100384Speter CP(ru, ru32, ru_nivcsw); 124127140Sjhb error = copyout(&ru32, uap->rusage, sizeof(ru32)); 125100384Speter } 126100384Speter return (error); 127100384Speter} 128100384Speter 129128597Smarcel#ifdef COMPAT_FREEBSD4 130100384Speterstatic void 131100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out) 132100384Speter{ 133100384Speter CP(*in, *out, f_bsize); 134100384Speter CP(*in, *out, f_iosize); 135100384Speter CP(*in, *out, f_blocks); 136100384Speter CP(*in, *out, f_bfree); 137100384Speter CP(*in, *out, f_bavail); 138100384Speter CP(*in, *out, f_files); 139100384Speter CP(*in, *out, f_ffree); 140100384Speter CP(*in, *out, f_fsid); 141100384Speter CP(*in, *out, f_owner); 142100384Speter CP(*in, *out, f_type); 143100384Speter CP(*in, *out, f_flags); 144100384Speter CP(*in, *out, f_flags); 145100384Speter CP(*in, *out, f_syncwrites); 146100384Speter CP(*in, *out, f_asyncwrites); 147100384Speter bcopy(in->f_fstypename, 148100384Speter out->f_fstypename, MFSNAMELEN); 149100384Speter bcopy(in->f_mntonname, 150128260Speter out->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 151100384Speter CP(*in, *out, f_syncreads); 152100384Speter CP(*in, *out, f_asyncreads); 153100384Speter bcopy(in->f_mntfromname, 154128260Speter out->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 155100384Speter} 156128597Smarcel#endif 157100384Speter 158128597Smarcel#ifdef COMPAT_FREEBSD4 159100384Speterint 160128260Speterfreebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap) 161100384Speter{ 162147178Spjd struct statfs *buf, *sp; 163147178Spjd struct statfs32 stat32; 164147178Spjd size_t count, size; 165100384Speter int error; 166100384Speter 167147178Spjd count = uap->bufsize / sizeof(struct statfs32); 168147178Spjd size = count * sizeof(struct statfs); 169147302Spjd error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags); 170147302Spjd if (size > 0) { 171100384Speter count = td->td_retval[0]; 172147178Spjd sp = buf; 173147178Spjd while (count > 0 && error == 0) { 174147178Spjd copy_statfs(sp, &stat32); 175147178Spjd error = copyout(&stat32, uap->buf, sizeof(stat32)); 176147178Spjd sp++; 177147178Spjd uap->buf++; 178147178Spjd count--; 179100384Speter } 180147178Spjd free(buf, M_TEMP); 181100384Speter } 182100384Speter return (error); 183100384Speter} 184128597Smarcel#endif 185100384Speter 186100384Speterstruct sigaltstack32 { 187100384Speter u_int32_t ss_sp; 188100384Speter u_int32_t ss_size; 189100384Speter int ss_flags; 190100384Speter}; 191100384Speter 192121719SpeterCTASSERT(sizeof(struct sigaltstack32) == 12); 193121719Speter 194100384Speterint 195119333Speterfreebsd32_sigaltstack(struct thread *td, 196119333Speter struct freebsd32_sigaltstack_args *uap) 197100384Speter{ 198113859Sjhb struct sigaltstack32 s32; 199113859Sjhb struct sigaltstack ss, oss, *ssp; 200100384Speter int error; 201100384Speter 202113859Sjhb if (uap->ss != NULL) { 203113859Sjhb error = copyin(uap->ss, &s32, sizeof(s32)); 204100384Speter if (error) 205100384Speter return (error); 206113859Sjhb PTRIN_CP(s32, ss, ss_sp); 207113859Sjhb CP(s32, ss, ss_size); 208113859Sjhb CP(s32, ss, ss_flags); 209113859Sjhb ssp = &ss; 210113859Sjhb } else 211113859Sjhb ssp = NULL; 212113859Sjhb error = kern_sigaltstack(td, ssp, &oss); 213113859Sjhb if (error == 0 && uap->oss != NULL) { 214113859Sjhb PTROUT_CP(oss, s32, ss_sp); 215113859Sjhb CP(oss, s32, ss_size); 216113859Sjhb CP(oss, s32, ss_flags); 217113859Sjhb error = copyout(&s32, uap->oss, sizeof(s32)); 218100384Speter } 219100384Speter return (error); 220100384Speter} 221100384Speter 222142059Sjhb/* 223142059Sjhb * Custom version of exec_copyin_args() so that we can translate 224142059Sjhb * the pointers. 225142059Sjhb */ 226142059Sjhbstatic int 227142059Sjhbfreebsd32_exec_copyin_args(struct image_args *args, char *fname, 228142059Sjhb enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv) 229100384Speter{ 230142059Sjhb char *argp, *envp; 231142059Sjhb u_int32_t *p32, arg; 232142059Sjhb size_t length; 233100384Speter int error; 234100384Speter 235142059Sjhb bzero(args, sizeof(*args)); 236142059Sjhb if (argv == NULL) 237142059Sjhb return (EFAULT); 238100384Speter 239142059Sjhb /* 240142059Sjhb * Allocate temporary demand zeroed space for argument and 241142059Sjhb * environment strings 242142059Sjhb */ 243147588Sjhb args->buf = (char *) kmem_alloc_wait(exec_map, 244147588Sjhb PATH_MAX + ARG_MAX + MAXSHELLCMDLEN); 245142059Sjhb if (args->buf == NULL) 246142059Sjhb return (ENOMEM); 247142059Sjhb args->begin_argv = args->buf; 248142059Sjhb args->endp = args->begin_argv; 249142059Sjhb args->stringspace = ARG_MAX; 250142059Sjhb 251142059Sjhb args->fname = args->buf + ARG_MAX; 252142059Sjhb 253142059Sjhb /* 254142059Sjhb * Copy the file name. 255142059Sjhb */ 256142059Sjhb error = (segflg == UIO_SYSSPACE) ? 257142059Sjhb copystr(fname, args->fname, PATH_MAX, &length) : 258142059Sjhb copyinstr(fname, args->fname, PATH_MAX, &length); 259142059Sjhb if (error != 0) 260142059Sjhb return (error); 261142059Sjhb 262142059Sjhb /* 263142059Sjhb * extract arguments first 264142059Sjhb */ 265142059Sjhb p32 = argv; 266142059Sjhb for (;;) { 267142059Sjhb error = copyin(p32++, &arg, sizeof(arg)); 268142059Sjhb if (error) 269142059Sjhb return (error); 270142059Sjhb if (arg == 0) 271142059Sjhb break; 272142059Sjhb argp = PTRIN(arg); 273142059Sjhb error = copyinstr(argp, args->endp, args->stringspace, &length); 274142059Sjhb if (error) { 275142059Sjhb if (error == ENAMETOOLONG) 276142059Sjhb return (E2BIG); 277142059Sjhb else 278142059Sjhb return (error); 279142059Sjhb } 280142059Sjhb args->stringspace -= length; 281142059Sjhb args->endp += length; 282142059Sjhb args->argc++; 283100384Speter } 284142059Sjhb 285142059Sjhb args->begin_envv = args->endp; 286142059Sjhb 287142059Sjhb /* 288142059Sjhb * extract environment strings 289142059Sjhb */ 290142059Sjhb if (envv) { 291142059Sjhb p32 = envv; 292142059Sjhb for (;;) { 293100384Speter error = copyin(p32++, &arg, sizeof(arg)); 294100384Speter if (error) 295142059Sjhb return (error); 296142059Sjhb if (arg == 0) 297142059Sjhb break; 298142059Sjhb envp = PTRIN(arg); 299142059Sjhb error = copyinstr(envp, args->endp, args->stringspace, 300142059Sjhb &length); 301142059Sjhb if (error) { 302142059Sjhb if (error == ENAMETOOLONG) 303142059Sjhb return (E2BIG); 304142059Sjhb else 305142059Sjhb return (error); 306142059Sjhb } 307142059Sjhb args->stringspace -= length; 308142059Sjhb args->endp += length; 309142059Sjhb args->envc++; 310142059Sjhb } 311100384Speter } 312100384Speter 313142059Sjhb return (0); 314100384Speter} 315100384Speter 316142059Sjhbint 317142059Sjhbfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) 318142059Sjhb{ 319142059Sjhb struct image_args eargs; 320142059Sjhb int error; 321142059Sjhb 322142059Sjhb error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE, 323142059Sjhb uap->argv, uap->envv); 324142059Sjhb if (error == 0) 325142059Sjhb error = kern_execve(td, &eargs, NULL); 326142059Sjhb exec_free_args(&eargs); 327142059Sjhb return (error); 328142059Sjhb} 329142059Sjhb 330114987Speter#ifdef __ia64__ 331100384Speterstatic int 332119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 333119333Speter int prot, int fd, off_t pos) 334100384Speter{ 335100384Speter vm_map_t map; 336100384Speter vm_map_entry_t entry; 337100384Speter int rv; 338100384Speter 339100384Speter map = &td->td_proc->p_vmspace->vm_map; 340100384Speter if (fd != -1) 341100384Speter prot |= VM_PROT_WRITE; 342100384Speter 343100384Speter if (vm_map_lookup_entry(map, start, &entry)) { 344100384Speter if ((entry->protection & prot) != prot) { 345100384Speter rv = vm_map_protect(map, 346100384Speter trunc_page(start), 347100384Speter round_page(end), 348100384Speter entry->protection | prot, 349100384Speter FALSE); 350100384Speter if (rv != KERN_SUCCESS) 351100384Speter return (EINVAL); 352100384Speter } 353100384Speter } else { 354100384Speter vm_offset_t addr = trunc_page(start); 355100384Speter rv = vm_map_find(map, 0, 0, 356100384Speter &addr, PAGE_SIZE, FALSE, prot, 357100384Speter VM_PROT_ALL, 0); 358100384Speter if (rv != KERN_SUCCESS) 359100384Speter return (EINVAL); 360100384Speter } 361100384Speter 362100384Speter if (fd != -1) { 363100384Speter struct pread_args r; 364107849Salfred r.fd = fd; 365107849Salfred r.buf = (void *) start; 366107849Salfred r.nbyte = end - start; 367107849Salfred r.offset = pos; 368100384Speter return (pread(td, &r)); 369100384Speter } else { 370100384Speter while (start < end) { 371100384Speter subyte((void *) start, 0); 372100384Speter start++; 373100384Speter } 374100384Speter return (0); 375100384Speter } 376100384Speter} 377114987Speter#endif 378100384Speter 379100384Speterint 380119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) 381100384Speter{ 382100384Speter struct mmap_args ap; 383107849Salfred vm_offset_t addr = (vm_offset_t) uap->addr; 384107849Salfred vm_size_t len = uap->len; 385107849Salfred int prot = uap->prot; 386107849Salfred int flags = uap->flags; 387107849Salfred int fd = uap->fd; 388107849Salfred off_t pos = (uap->poslo 389107849Salfred | ((off_t)uap->poshi << 32)); 390114987Speter#ifdef __ia64__ 391100384Speter vm_size_t pageoff; 392100384Speter int error; 393100384Speter 394100384Speter /* 395100384Speter * Attempt to handle page size hassles. 396100384Speter */ 397100384Speter pageoff = (pos & PAGE_MASK); 398100384Speter if (flags & MAP_FIXED) { 399100384Speter vm_offset_t start, end; 400100384Speter start = addr; 401100384Speter end = addr + len; 402100384Speter 403147964Sjhb mtx_lock(&Giant); 404100384Speter if (start != trunc_page(start)) { 405119333Speter error = freebsd32_mmap_partial(td, start, 406119333Speter round_page(start), prot, 407119333Speter fd, pos); 408100384Speter if (fd != -1) 409100384Speter pos += round_page(start) - start; 410100384Speter start = round_page(start); 411100384Speter } 412100384Speter if (end != round_page(end)) { 413100384Speter vm_offset_t t = trunc_page(end); 414119333Speter error = freebsd32_mmap_partial(td, t, end, 415100384Speter prot, fd, 416100384Speter pos + t - start); 417100384Speter end = trunc_page(end); 418100384Speter } 419100384Speter if (end > start && fd != -1 && (pos & PAGE_MASK)) { 420100384Speter /* 421100384Speter * We can't map this region at all. The specified 422100384Speter * address doesn't have the same alignment as the file 423100384Speter * position. Fake the mapping by simply reading the 424100384Speter * entire region into memory. First we need to make 425100384Speter * sure the region exists. 426100384Speter */ 427100384Speter vm_map_t map; 428100384Speter struct pread_args r; 429100384Speter int rv; 430100384Speter 431100384Speter prot |= VM_PROT_WRITE; 432100384Speter map = &td->td_proc->p_vmspace->vm_map; 433100384Speter rv = vm_map_remove(map, start, end); 434147964Sjhb if (rv != KERN_SUCCESS) { 435147964Sjhb mtx_unlock(&Giant); 436100384Speter return (EINVAL); 437147964Sjhb } 438100384Speter rv = vm_map_find(map, 0, 0, 439100384Speter &start, end - start, FALSE, 440100384Speter prot, VM_PROT_ALL, 0); 441147964Sjhb mtx_unlock(&Giant); 442100384Speter if (rv != KERN_SUCCESS) 443100384Speter return (EINVAL); 444107849Salfred r.fd = fd; 445107849Salfred r.buf = (void *) start; 446107849Salfred r.nbyte = end - start; 447107849Salfred r.offset = pos; 448100384Speter error = pread(td, &r); 449100384Speter if (error) 450100384Speter return (error); 451100384Speter 452100384Speter td->td_retval[0] = addr; 453100384Speter return (0); 454100384Speter } 455147964Sjhb mtx_unlock(&Giant); 456100384Speter if (end == start) { 457100384Speter /* 458100384Speter * After dealing with the ragged ends, there 459100384Speter * might be none left. 460100384Speter */ 461100384Speter td->td_retval[0] = addr; 462100384Speter return (0); 463100384Speter } 464100384Speter addr = start; 465100384Speter len = end - start; 466100384Speter } 467114987Speter#endif 468100384Speter 469107849Salfred ap.addr = (void *) addr; 470107849Salfred ap.len = len; 471107849Salfred ap.prot = prot; 472107849Salfred ap.flags = flags; 473107849Salfred ap.fd = fd; 474107849Salfred ap.pos = pos; 475100384Speter 476100384Speter return (mmap(td, &ap)); 477100384Speter} 478100384Speter 479100384Speterstruct itimerval32 { 480100384Speter struct timeval32 it_interval; 481100384Speter struct timeval32 it_value; 482100384Speter}; 483100384Speter 484121719SpeterCTASSERT(sizeof(struct itimerval32) == 16); 485121719Speter 486100384Speterint 487119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap) 488100384Speter{ 489142059Sjhb struct itimerval itv, oitv, *itvp; 490142059Sjhb struct itimerval32 i32; 491100384Speter int error; 492100384Speter 493142059Sjhb if (uap->itv != NULL) { 494142059Sjhb error = copyin(uap->itv, &i32, sizeof(i32)); 495100384Speter if (error) 496100384Speter return (error); 497142059Sjhb TV_CP(i32, itv, it_interval); 498142059Sjhb TV_CP(i32, itv, it_value); 499142059Sjhb itvp = &itv; 500142059Sjhb } else 501142059Sjhb itvp = NULL; 502142059Sjhb error = kern_setitimer(td, uap->which, itvp, &oitv); 503142059Sjhb if (error || uap->oitv == NULL) 504100384Speter return (error); 505142059Sjhb TV_CP(oitv, i32, it_interval); 506142059Sjhb TV_CP(oitv, i32, it_value); 507142059Sjhb return (copyout(&i32, uap->oitv, sizeof(i32))); 508100384Speter} 509100384Speter 510100384Speterint 511125171Speterfreebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap) 512125171Speter{ 513142059Sjhb struct itimerval itv; 514142059Sjhb struct itimerval32 i32; 515125171Speter int error; 516125171Speter 517142059Sjhb error = kern_getitimer(td, uap->which, &itv); 518142059Sjhb if (error || uap->itv == NULL) 519125171Speter return (error); 520142059Sjhb TV_CP(itv, i32, it_interval); 521142059Sjhb TV_CP(itv, i32, it_value); 522142059Sjhb return (copyout(&i32, uap->itv, sizeof(i32))); 523125171Speter} 524125171Speter 525125171Speterint 526119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap) 527100384Speter{ 528142059Sjhb struct timeval32 tv32; 529142059Sjhb struct timeval tv, *tvp; 530100384Speter int error; 531100384Speter 532142059Sjhb if (uap->tv != NULL) { 533142059Sjhb error = copyin(uap->tv, &tv32, sizeof(tv32)); 534100384Speter if (error) 535100384Speter return (error); 536142059Sjhb CP(tv32, tv, tv_sec); 537142059Sjhb CP(tv32, tv, tv_usec); 538142059Sjhb tvp = &tv; 539142059Sjhb } else 540142059Sjhb tvp = NULL; 541100384Speter /* 542100384Speter * XXX big-endian needs to convert the fd_sets too. 543142059Sjhb * XXX Do pointers need PTRIN()? 544100384Speter */ 545142059Sjhb return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp)); 546100384Speter} 547100384Speter 548114987Speterstruct kevent32 { 549114987Speter u_int32_t ident; /* identifier for this event */ 550114987Speter short filter; /* filter for event */ 551114987Speter u_short flags; 552114987Speter u_int fflags; 553114987Speter int32_t data; 554114987Speter u_int32_t udata; /* opaque user data identifier */ 555114987Speter}; 556114987Speter 557121719SpeterCTASSERT(sizeof(struct kevent32) == 20); 558146950Spsstatic int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count); 559146950Spsstatic int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count); 560121719Speter 561146950Sps/* 562146950Sps * Copy 'count' items into the destination list pointed to by uap->eventlist. 563146950Sps */ 564146950Spsstatic int 565146950Spsfreebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count) 566146950Sps{ 567146950Sps struct freebsd32_kevent_args *uap; 568146950Sps struct kevent32 ks32[KQ_NEVENTS]; 569146950Sps int i, error = 0; 570146950Sps 571146950Sps KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count)); 572146950Sps uap = (struct freebsd32_kevent_args *)arg; 573146950Sps 574146950Sps for (i = 0; i < count; i++) { 575146950Sps CP(kevp[i], ks32[i], ident); 576146950Sps CP(kevp[i], ks32[i], filter); 577146950Sps CP(kevp[i], ks32[i], flags); 578146950Sps CP(kevp[i], ks32[i], fflags); 579146950Sps CP(kevp[i], ks32[i], data); 580146950Sps PTROUT_CP(kevp[i], ks32[i], udata); 581146950Sps } 582146950Sps error = copyout(ks32, uap->eventlist, count * sizeof *ks32); 583146950Sps if (error == 0) 584146950Sps uap->eventlist += count; 585146950Sps return (error); 586146950Sps} 587146950Sps 588146950Sps/* 589146950Sps * Copy 'count' items from the list pointed to by uap->changelist. 590146950Sps */ 591146950Spsstatic int 592146950Spsfreebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count) 593146950Sps{ 594146950Sps struct freebsd32_kevent_args *uap; 595146950Sps struct kevent32 ks32[KQ_NEVENTS]; 596146950Sps int i, error = 0; 597146950Sps 598146950Sps KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count)); 599146950Sps uap = (struct freebsd32_kevent_args *)arg; 600146950Sps 601146950Sps error = copyin(uap->changelist, ks32, count * sizeof *ks32); 602146950Sps if (error) 603146950Sps goto done; 604146950Sps uap->changelist += count; 605146950Sps 606146950Sps for (i = 0; i < count; i++) { 607146950Sps CP(ks32[i], kevp[i], ident); 608146950Sps CP(ks32[i], kevp[i], filter); 609146950Sps CP(ks32[i], kevp[i], flags); 610146950Sps CP(ks32[i], kevp[i], fflags); 611146950Sps CP(ks32[i], kevp[i], data); 612146950Sps PTRIN_CP(ks32[i], kevp[i], udata); 613146950Sps } 614146950Spsdone: 615146950Sps return (error); 616146950Sps} 617146950Sps 618100384Speterint 619119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap) 620114987Speter{ 621114987Speter struct timespec32 ts32; 622142934Sps struct timespec ts, *tsp; 623146950Sps struct kevent_copyops k_ops = { uap, 624146950Sps freebsd32_kevent_copyout, 625146950Sps freebsd32_kevent_copyin}; 626146950Sps int error; 627114987Speter 628114987Speter 629114987Speter if (uap->timeout) { 630114987Speter error = copyin(uap->timeout, &ts32, sizeof(ts32)); 631114987Speter if (error) 632114987Speter return (error); 633114987Speter CP(ts32, ts, tv_sec); 634114987Speter CP(ts32, ts, tv_nsec); 635142934Sps tsp = &ts; 636142934Sps } else 637142934Sps tsp = NULL; 638146950Sps error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents, 639146950Sps &k_ops, tsp); 640142934Sps return (error); 641114987Speter} 642114987Speter 643114987Speterint 644119333Speterfreebsd32_gettimeofday(struct thread *td, 645119333Speter struct freebsd32_gettimeofday_args *uap) 646100384Speter{ 647123425Speter struct timeval atv; 648123425Speter struct timeval32 atv32; 649123425Speter struct timezone rtz; 650123425Speter int error = 0; 651100384Speter 652123425Speter if (uap->tp) { 653123425Speter microtime(&atv); 654123425Speter CP(atv, atv32, tv_sec); 655123425Speter CP(atv, atv32, tv_usec); 656123425Speter error = copyout(&atv32, uap->tp, sizeof (atv32)); 657100384Speter } 658123425Speter if (error == 0 && uap->tzp != NULL) { 659123425Speter rtz.tz_minuteswest = tz_minuteswest; 660123425Speter rtz.tz_dsttime = tz_dsttime; 661123425Speter error = copyout(&rtz, uap->tzp, sizeof (rtz)); 662100384Speter } 663100384Speter return (error); 664100384Speter} 665100384Speter 666100384Speterint 667119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap) 668100384Speter{ 669136152Sjhb struct rusage32 s32; 670136152Sjhb struct rusage s; 671100384Speter int error; 672100384Speter 673136152Sjhb error = kern_getrusage(td, uap->who, &s); 674100384Speter if (error) 675100384Speter return (error); 676136152Sjhb if (uap->rusage != NULL) { 677100384Speter TV_CP(s, s32, ru_utime); 678100384Speter TV_CP(s, s32, ru_stime); 679100384Speter CP(s, s32, ru_maxrss); 680100384Speter CP(s, s32, ru_ixrss); 681100384Speter CP(s, s32, ru_idrss); 682100384Speter CP(s, s32, ru_isrss); 683100384Speter CP(s, s32, ru_minflt); 684100384Speter CP(s, s32, ru_majflt); 685100384Speter CP(s, s32, ru_nswap); 686100384Speter CP(s, s32, ru_inblock); 687100384Speter CP(s, s32, ru_oublock); 688100384Speter CP(s, s32, ru_msgsnd); 689100384Speter CP(s, s32, ru_msgrcv); 690100384Speter CP(s, s32, ru_nsignals); 691100384Speter CP(s, s32, ru_nvcsw); 692100384Speter CP(s, s32, ru_nivcsw); 693136152Sjhb error = copyout(&s32, uap->rusage, sizeof(s32)); 694100384Speter } 695100384Speter return (error); 696100384Speter} 697100384Speter 698100384Speterstruct iovec32 { 699100384Speter u_int32_t iov_base; 700100384Speter int iov_len; 701100384Speter}; 702100384Speter 703121719SpeterCTASSERT(sizeof(struct iovec32) == 8); 704121719Speter 705144450Sjhbstatic int 706144450Sjhbfreebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop) 707100384Speter{ 708144450Sjhb struct iovec32 iov32; 709144450Sjhb struct iovec *iov; 710144450Sjhb struct uio *uio; 711144450Sjhb u_int iovlen; 712144450Sjhb int error, i; 713100384Speter 714144450Sjhb *uiop = NULL; 715144450Sjhb if (iovcnt > UIO_MAXIOV) 716100384Speter return (EINVAL); 717144450Sjhb iovlen = iovcnt * sizeof(struct iovec); 718144450Sjhb uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK); 719144450Sjhb iov = (struct iovec *)(uio + 1); 720144450Sjhb for (i = 0; i < iovcnt; i++) { 721144450Sjhb error = copyin(&iovp[i], &iov32, sizeof(struct iovec32)); 722144450Sjhb if (error) { 723144450Sjhb free(uio, M_IOV); 724144450Sjhb return (error); 725144450Sjhb } 726144450Sjhb iov[i].iov_base = PTRIN(iov32.iov_base); 727144450Sjhb iov[i].iov_len = iov32.iov_len; 728100384Speter } 729144450Sjhb uio->uio_iov = iov; 730144450Sjhb uio->uio_iovcnt = iovcnt; 731144450Sjhb uio->uio_segflg = UIO_USERSPACE; 732144450Sjhb uio->uio_offset = -1; 733144450Sjhb uio->uio_resid = 0; 734144450Sjhb for (i = 0; i < iovcnt; i++) { 735144450Sjhb if (iov->iov_len > INT_MAX - uio->uio_resid) { 736144450Sjhb free(uio, M_IOV); 737144450Sjhb return (EINVAL); 738144450Sjhb } 739144450Sjhb uio->uio_resid += iov->iov_len; 740144450Sjhb iov++; 741144450Sjhb } 742144450Sjhb *uiop = uio; 743144450Sjhb return (0); 744144450Sjhb} 745100384Speter 746144450Sjhbint 747144450Sjhbfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) 748144450Sjhb{ 749144450Sjhb struct uio *auio; 750144450Sjhb int error; 751100384Speter 752144450Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 753144450Sjhb if (error) 754144450Sjhb return (error); 755144450Sjhb error = kern_readv(td, uap->fd, auio); 756144450Sjhb free(auio, M_IOV); 757100384Speter return (error); 758100384Speter} 759100384Speter 760100384Speterint 761119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) 762100384Speter{ 763144450Sjhb struct uio *auio; 764144450Sjhb int error; 765100384Speter 766144450Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 767144450Sjhb if (error) 768144450Sjhb return (error); 769144450Sjhb error = kern_writev(td, uap->fd, auio); 770144450Sjhb free(auio, M_IOV); 771100384Speter return (error); 772100384Speter} 773100384Speter 774100384Speterint 775147813Sjhbfreebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap) 776147813Sjhb{ 777147813Sjhb struct uio *auio; 778147813Sjhb int error; 779147813Sjhb 780147813Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 781147813Sjhb if (error) 782147813Sjhb return (error); 783147813Sjhb error = kern_preadv(td, uap->fd, auio, uap->offset); 784147813Sjhb free(auio, M_IOV); 785147813Sjhb return (error); 786147813Sjhb} 787147813Sjhb 788147813Sjhbint 789147813Sjhbfreebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap) 790147813Sjhb{ 791147813Sjhb struct uio *auio; 792147813Sjhb int error; 793147813Sjhb 794147813Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 795147813Sjhb if (error) 796147813Sjhb return (error); 797147813Sjhb error = kern_pwritev(td, uap->fd, auio, uap->offset); 798147813Sjhb free(auio, M_IOV); 799147813Sjhb return (error); 800147813Sjhb} 801147813Sjhb 802151359Spsstatic int 803151359Spsfreebsd32_copyiniov(struct iovec32 *iovp, u_int iovcnt, struct iovec **iov, 804151359Sps int error) 805151359Sps{ 806151359Sps struct iovec32 iov32; 807151359Sps int i; 808151359Sps 809151359Sps u_int iovlen; 810151359Sps 811151359Sps *iov = NULL; 812151359Sps if (iovcnt > UIO_MAXIOV) 813151359Sps return (error); 814151359Sps iovlen = iovcnt * sizeof(struct iovec); 815151359Sps *iov = malloc(iovlen, M_IOV, M_WAITOK); 816151359Sps for (i = 0; i < iovcnt; i++) { 817151359Sps error = copyin(&iovp[i], &iov32, sizeof(struct iovec32)); 818151359Sps if (error) { 819151359Sps free(*iov, M_IOV); 820151359Sps *iov = NULL; 821151359Sps return (error); 822151359Sps } 823151359Sps iov[i]->iov_base = PTRIN(iov32.iov_base); 824151359Sps iov[i]->iov_len = iov32.iov_len; 825151359Sps } 826151359Sps return (0); 827151359Sps} 828151359Sps 829151359Spsstruct msghdr32 { 830151359Sps u_int32_t msg_name; 831151359Sps socklen_t msg_namelen; 832151359Sps u_int32_t msg_iov; 833151359Sps int msg_iovlen; 834151359Sps u_int32_t msg_control; 835151359Sps socklen_t msg_controllen; 836151359Sps int msg_flags; 837151359Sps}; 838151359SpsCTASSERT(sizeof(struct msghdr32) == 28); 839151359Sps 840151359Spsstatic int 841151359Spsfreebsd32_copyinmsghdr(struct msghdr32 *msg32, struct msghdr *msg) 842151359Sps{ 843151359Sps struct msghdr32 m32; 844151359Sps int error; 845151359Sps 846151359Sps error = copyin(msg32, &m32, sizeof(m32)); 847151359Sps if (error) 848151359Sps return (error); 849151359Sps msg->msg_name = PTRIN(m32.msg_name); 850151359Sps msg->msg_namelen = m32.msg_namelen; 851151359Sps msg->msg_iov = PTRIN(m32.msg_iov); 852151359Sps msg->msg_iovlen = m32.msg_iovlen; 853151359Sps msg->msg_control = PTRIN(m32.msg_control); 854151359Sps msg->msg_controllen = m32.msg_controllen; 855151359Sps msg->msg_flags = m32.msg_flags; 856151359Sps return (freebsd32_copyiniov((struct iovec32 *)(uintptr_t)m32.msg_iov, m32.msg_iovlen, &msg->msg_iov, 857151359Sps EMSGSIZE)); 858151359Sps} 859151359Sps 860151359Spsstatic int 861151359Spsfreebsd32_copyoutmsghdr(struct msghdr *msg, struct msghdr32 *msg32) 862151359Sps{ 863151359Sps struct msghdr32 m32; 864151359Sps int error; 865151359Sps 866151359Sps m32.msg_name = PTROUT(msg->msg_name); 867151359Sps m32.msg_namelen = msg->msg_namelen; 868151359Sps m32.msg_iov = PTROUT(msg->msg_iov); 869151359Sps m32.msg_iovlen = msg->msg_iovlen; 870151359Sps m32.msg_control = PTROUT(msg->msg_control); 871151359Sps m32.msg_controllen = msg->msg_controllen; 872151359Sps m32.msg_flags = msg->msg_flags; 873151359Sps error = copyout(&m32, msg32, sizeof(m32)); 874151359Sps return (error); 875151359Sps} 876151359Sps 877147813Sjhbint 878151359Spsfreebsd32_recvmsg(td, uap) 879151359Sps struct thread *td; 880151359Sps struct freebsd32_recvmsg_args /* { 881151359Sps int s; 882151359Sps struct msghdr32 *msg; 883151359Sps int flags; 884151359Sps } */ *uap; 885151359Sps{ 886151359Sps struct msghdr msg; 887151359Sps struct msghdr32 m32; 888151359Sps struct iovec *uiov, *iov; 889151359Sps int error; 890151359Sps 891151359Sps error = copyin(uap->msg, &m32, sizeof(m32)); 892151359Sps if (error) 893151359Sps return (error); 894151359Sps error = freebsd32_copyinmsghdr(uap->msg, &msg); 895151359Sps if (error) 896151359Sps return (error); 897151359Sps error = freebsd32_copyiniov((struct iovec32 *)(uintptr_t)m32.msg_iov, 898151359Sps m32.msg_iovlen, &iov, EMSGSIZE); 899151359Sps if (error) 900151359Sps return (error); 901151359Sps msg.msg_flags = uap->flags; 902151359Sps uiov = msg.msg_iov; 903151359Sps msg.msg_iov = iov; 904151359Sps error = kern_recvit(td, uap->s, &msg, NULL, UIO_SYSSPACE); 905151359Sps if (error == 0) { 906151359Sps msg.msg_iov = uiov; 907151359Sps error = freebsd32_copyoutmsghdr(&msg, uap->msg); 908151359Sps } 909151359Sps free(iov, M_IOV); 910151359Sps free(uiov, M_IOV); 911151359Sps return (error); 912151359Sps} 913151359Sps 914151359Spsint 915151359Spsfreebsd32_sendmsg(struct thread *td, 916151359Sps struct freebsd32_sendmsg_args *uap) 917151359Sps{ 918151359Sps struct msghdr msg; 919151359Sps struct msghdr32 m32; 920151359Sps struct iovec *iov; 921151359Sps int error; 922151359Sps 923151359Sps error = copyin(uap->msg, &m32, sizeof(m32)); 924151359Sps if (error) 925151359Sps return (error); 926151359Sps error = freebsd32_copyinmsghdr(uap->msg, &msg); 927151359Sps if (error) 928151359Sps return (error); 929151359Sps error = freebsd32_copyiniov((struct iovec32 *)(uintptr_t)m32.msg_iov, 930151359Sps m32.msg_iovlen, &iov, EMSGSIZE); 931151359Sps if (error) 932151359Sps return (error); 933151359Sps msg.msg_iov = iov; 934151359Sps error = kern_sendit(td, uap->s, &msg, uap->flags, NULL, UIO_SYSSPACE); 935151359Sps free(iov, M_IOV); 936151359Sps return (error); 937151359Sps} 938151359Sps 939151359Spsint 940151359Spsfreebsd32_recvfrom(struct thread *td, 941151359Sps struct freebsd32_recvfrom_args *uap) 942151359Sps{ 943151359Sps struct msghdr msg; 944151359Sps struct iovec aiov; 945151359Sps int error; 946151359Sps 947151359Sps if (uap->fromlenaddr) { 948151359Sps error = copyin((void *)(uintptr_t)uap->fromlenaddr, 949151359Sps &msg.msg_namelen, sizeof(msg.msg_namelen)); 950151359Sps if (error) 951151359Sps return (error); 952151359Sps } else { 953151359Sps msg.msg_namelen = 0; 954151359Sps } 955151359Sps 956151359Sps msg.msg_name = (void *)(uintptr_t)uap->from; 957151359Sps msg.msg_iov = &aiov; 958151359Sps msg.msg_iovlen = 1; 959151359Sps aiov.iov_base = (void *)(uintptr_t)uap->buf; 960151359Sps aiov.iov_len = uap->len; 961151359Sps msg.msg_control = 0; 962151359Sps msg.msg_flags = uap->flags; 963151359Sps error = kern_recvit(td, uap->s, &msg, (void *)(uintptr_t)uap->fromlenaddr, UIO_USERSPACE); 964151359Sps return (error); 965151359Sps} 966151359Sps 967151359Spsint 968119333Speterfreebsd32_settimeofday(struct thread *td, 969119333Speter struct freebsd32_settimeofday_args *uap) 970100384Speter{ 971144450Sjhb struct timeval32 tv32; 972144450Sjhb struct timeval tv, *tvp; 973144450Sjhb struct timezone tz, *tzp; 974100384Speter int error; 975100384Speter 976144450Sjhb if (uap->tv) { 977144450Sjhb error = copyin(uap->tv, &tv32, sizeof(tv32)); 978100384Speter if (error) 979100384Speter return (error); 980144450Sjhb CP(tv32, tv, tv_sec); 981144450Sjhb CP(tv32, tv, tv_usec); 982144450Sjhb tvp = &tv; 983144450Sjhb } else 984144450Sjhb tvp = NULL; 985144450Sjhb if (uap->tzp) { 986144450Sjhb error = copyin(uap->tzp, &tz, sizeof(tz)); 987100384Speter if (error) 988100384Speter return (error); 989144450Sjhb tzp = &tz; 990144450Sjhb } else 991144450Sjhb tzp = NULL; 992144450Sjhb return (kern_settimeofday(td, tvp, tzp)); 993100384Speter} 994100384Speter 995100384Speterint 996119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap) 997100384Speter{ 998142059Sjhb struct timeval32 s32[2]; 999142059Sjhb struct timeval s[2], *sp; 1000100384Speter int error; 1001100384Speter 1002142059Sjhb if (uap->tptr != NULL) { 1003142059Sjhb error = copyin(uap->tptr, s32, sizeof(s32)); 1004100384Speter if (error) 1005100384Speter return (error); 1006100384Speter CP(s32[0], s[0], tv_sec); 1007100384Speter CP(s32[0], s[0], tv_usec); 1008100384Speter CP(s32[1], s[1], tv_sec); 1009100384Speter CP(s32[1], s[1], tv_usec); 1010142059Sjhb sp = s; 1011142059Sjhb } else 1012142059Sjhb sp = NULL; 1013142059Sjhb return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE)); 1014100384Speter} 1015100384Speter 1016100384Speterint 1017119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) 1018100384Speter{ 1019144450Sjhb struct timeval32 tv32; 1020144450Sjhb struct timeval delta, olddelta, *deltap; 1021100384Speter int error; 1022100384Speter 1023144450Sjhb if (uap->delta) { 1024144450Sjhb error = copyin(uap->delta, &tv32, sizeof(tv32)); 1025100384Speter if (error) 1026100384Speter return (error); 1027144450Sjhb CP(tv32, delta, tv_sec); 1028144450Sjhb CP(tv32, delta, tv_usec); 1029144450Sjhb deltap = δ 1030144450Sjhb } else 1031144450Sjhb deltap = NULL; 1032144450Sjhb error = kern_adjtime(td, deltap, &olddelta); 1033144450Sjhb if (uap->olddelta && error == 0) { 1034144450Sjhb CP(olddelta, tv32, tv_sec); 1035144450Sjhb CP(olddelta, tv32, tv_usec); 1036144450Sjhb error = copyout(&tv32, uap->olddelta, sizeof(tv32)); 1037100384Speter } 1038100384Speter return (error); 1039100384Speter} 1040100384Speter 1041128597Smarcel#ifdef COMPAT_FREEBSD4 1042100384Speterint 1043128260Speterfreebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap) 1044100384Speter{ 1045142059Sjhb struct statfs32 s32; 1046142059Sjhb struct statfs s; 1047100384Speter int error; 1048100384Speter 1049142059Sjhb error = kern_statfs(td, uap->path, UIO_USERSPACE, &s); 1050100384Speter if (error) 1051100384Speter return (error); 1052142059Sjhb copy_statfs(&s, &s32); 1053142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 1054100384Speter} 1055128597Smarcel#endif 1056100384Speter 1057128597Smarcel#ifdef COMPAT_FREEBSD4 1058100384Speterint 1059128260Speterfreebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap) 1060100384Speter{ 1061142059Sjhb struct statfs32 s32; 1062142059Sjhb struct statfs s; 1063100384Speter int error; 1064100384Speter 1065142059Sjhb error = kern_fstatfs(td, uap->fd, &s); 1066100384Speter if (error) 1067100384Speter return (error); 1068142059Sjhb copy_statfs(&s, &s32); 1069142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 1070100384Speter} 1071128597Smarcel#endif 1072100384Speter 1073128597Smarcel#ifdef COMPAT_FREEBSD4 1074100384Speterint 1075128260Speterfreebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap) 1076128260Speter{ 1077142059Sjhb struct statfs32 s32; 1078142059Sjhb struct statfs s; 1079142059Sjhb fhandle_t fh; 1080128260Speter int error; 1081128260Speter 1082142059Sjhb if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0) 1083142059Sjhb return (error); 1084142059Sjhb error = kern_fhstatfs(td, fh, &s); 1085128260Speter if (error) 1086128260Speter return (error); 1087142059Sjhb copy_statfs(&s, &s32); 1088142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 1089128260Speter} 1090128597Smarcel#endif 1091128260Speter 1092128260Speterint 1093119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap) 1094100384Speter{ 1095100384Speter /* 1096100384Speter * Vector through to semsys if it is loaded. 1097100384Speter */ 1098150883Sjhb return sysent[SYS_semsys].sy_call(td, uap); 1099100384Speter} 1100100384Speter 1101100384Speterint 1102119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap) 1103100384Speter{ 1104100384Speter /* 1105100384Speter * Vector through to msgsys if it is loaded. 1106100384Speter */ 1107150883Sjhb return sysent[SYS_msgsys].sy_call(td, uap); 1108100384Speter} 1109100384Speter 1110100384Speterint 1111119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap) 1112100384Speter{ 1113100384Speter /* 1114100384Speter * Vector through to shmsys if it is loaded. 1115100384Speter */ 1116150883Sjhb return sysent[SYS_shmsys].sy_call(td, uap); 1117100384Speter} 1118100384Speter 1119100384Speterint 1120119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) 1121100384Speter{ 1122100384Speter struct pread_args ap; 1123100384Speter 1124107849Salfred ap.fd = uap->fd; 1125107849Salfred ap.buf = uap->buf; 1126107849Salfred ap.nbyte = uap->nbyte; 1127119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1128100384Speter return (pread(td, &ap)); 1129100384Speter} 1130100384Speter 1131100384Speterint 1132119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap) 1133100384Speter{ 1134100384Speter struct pwrite_args ap; 1135100384Speter 1136107849Salfred ap.fd = uap->fd; 1137107849Salfred ap.buf = uap->buf; 1138107849Salfred ap.nbyte = uap->nbyte; 1139119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1140100384Speter return (pwrite(td, &ap)); 1141100384Speter} 1142100384Speter 1143100384Speterint 1144119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap) 1145100384Speter{ 1146100384Speter int error; 1147100384Speter struct lseek_args ap; 1148100384Speter off_t pos; 1149100384Speter 1150107849Salfred ap.fd = uap->fd; 1151119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1152107849Salfred ap.whence = uap->whence; 1153100384Speter error = lseek(td, &ap); 1154100384Speter /* Expand the quad return into two parts for eax and edx */ 1155100384Speter pos = *(off_t *)(td->td_retval); 1156100384Speter td->td_retval[0] = pos & 0xffffffff; /* %eax */ 1157100384Speter td->td_retval[1] = pos >> 32; /* %edx */ 1158100384Speter return error; 1159100384Speter} 1160100384Speter 1161100384Speterint 1162119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap) 1163100384Speter{ 1164100384Speter struct truncate_args ap; 1165100384Speter 1166107849Salfred ap.path = uap->path; 1167119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1168100384Speter return (truncate(td, &ap)); 1169100384Speter} 1170100384Speter 1171100384Speterint 1172119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) 1173100384Speter{ 1174100384Speter struct ftruncate_args ap; 1175100384Speter 1176107849Salfred ap.fd = uap->fd; 1177119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1178100384Speter return (ftruncate(td, &ap)); 1179100384Speter} 1180100384Speter 1181104738Speter#ifdef COMPAT_FREEBSD4 1182100384Speterint 1183119333Speterfreebsd4_freebsd32_sendfile(struct thread *td, 1184119333Speter struct freebsd4_freebsd32_sendfile_args *uap) 1185104738Speter{ 1186104738Speter struct freebsd4_sendfile_args ap; 1187104738Speter 1188107849Salfred ap.fd = uap->fd; 1189107849Salfred ap.s = uap->s; 1190119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1191107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1192107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1193107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1194107849Salfred ap.flags = uap->flags; 1195104738Speter return (freebsd4_sendfile(td, &ap)); 1196104738Speter} 1197104738Speter#endif 1198104738Speter 1199104738Speterint 1200119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap) 1201100384Speter{ 1202100384Speter struct sendfile_args ap; 1203100384Speter 1204107849Salfred ap.fd = uap->fd; 1205107849Salfred ap.s = uap->s; 1206119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1207107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1208107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1209107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1210107849Salfred ap.flags = uap->flags; 1211100384Speter return (sendfile(td, &ap)); 1212100384Speter} 1213100384Speter 1214100384Speterstruct stat32 { 1215130640Sphk dev_t st_dev; 1216100384Speter ino_t st_ino; 1217100384Speter mode_t st_mode; 1218100384Speter nlink_t st_nlink; 1219100384Speter uid_t st_uid; 1220100384Speter gid_t st_gid; 1221130640Sphk dev_t st_rdev; 1222100384Speter struct timespec32 st_atimespec; 1223100384Speter struct timespec32 st_mtimespec; 1224100384Speter struct timespec32 st_ctimespec; 1225100384Speter off_t st_size; 1226100384Speter int64_t st_blocks; 1227100384Speter u_int32_t st_blksize; 1228100384Speter u_int32_t st_flags; 1229100384Speter u_int32_t st_gen; 1230121719Speter struct timespec32 st_birthtimespec; 1231121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1232121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1233100384Speter}; 1234100384Speter 1235121719Speter 1236121719SpeterCTASSERT(sizeof(struct stat32) == 96); 1237121719Speter 1238100384Speterstatic void 1239100384Spetercopy_stat( struct stat *in, struct stat32 *out) 1240100384Speter{ 1241100384Speter CP(*in, *out, st_dev); 1242100384Speter CP(*in, *out, st_ino); 1243100384Speter CP(*in, *out, st_mode); 1244100384Speter CP(*in, *out, st_nlink); 1245100384Speter CP(*in, *out, st_uid); 1246100384Speter CP(*in, *out, st_gid); 1247100384Speter CP(*in, *out, st_rdev); 1248100384Speter TS_CP(*in, *out, st_atimespec); 1249100384Speter TS_CP(*in, *out, st_mtimespec); 1250100384Speter TS_CP(*in, *out, st_ctimespec); 1251100384Speter CP(*in, *out, st_size); 1252100384Speter CP(*in, *out, st_blocks); 1253100384Speter CP(*in, *out, st_blksize); 1254100384Speter CP(*in, *out, st_flags); 1255100384Speter CP(*in, *out, st_gen); 1256100384Speter} 1257100384Speter 1258100384Speterint 1259119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap) 1260100384Speter{ 1261123746Speter struct stat sb; 1262123746Speter struct stat32 sb32; 1263100384Speter int error; 1264100384Speter 1265142059Sjhb error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 1266100384Speter if (error) 1267100384Speter return (error); 1268123746Speter copy_stat(&sb, &sb32); 1269123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1270100384Speter return (error); 1271100384Speter} 1272100384Speter 1273100384Speterint 1274119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap) 1275100384Speter{ 1276123746Speter struct stat ub; 1277123746Speter struct stat32 ub32; 1278100384Speter int error; 1279100384Speter 1280142059Sjhb error = kern_fstat(td, uap->fd, &ub); 1281100384Speter if (error) 1282100384Speter return (error); 1283123746Speter copy_stat(&ub, &ub32); 1284123746Speter error = copyout(&ub32, uap->ub, sizeof(ub32)); 1285100384Speter return (error); 1286100384Speter} 1287100384Speter 1288100384Speterint 1289119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap) 1290100384Speter{ 1291123746Speter struct stat sb; 1292123746Speter struct stat32 sb32; 1293142059Sjhb int error; 1294100384Speter 1295142059Sjhb error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 1296100384Speter if (error) 1297100384Speter return (error); 1298123746Speter copy_stat(&sb, &sb32); 1299123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1300100384Speter return (error); 1301100384Speter} 1302100384Speter 1303100384Speter/* 1304100384Speter * MPSAFE 1305100384Speter */ 1306100384Speterint 1307119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap) 1308100384Speter{ 1309100384Speter int error, name[CTL_MAXNAME]; 1310100384Speter size_t j, oldlen; 1311100384Speter 1312100384Speter if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1313100384Speter return (EINVAL); 1314136404Speter error = copyin(uap->name, name, uap->namelen * sizeof(int)); 1315100384Speter if (error) 1316100384Speter return (error); 1317100384Speter mtx_lock(&Giant); 1318100384Speter if (uap->oldlenp) 1319100384Speter oldlen = fuword32(uap->oldlenp); 1320100384Speter else 1321100384Speter oldlen = 0; 1322100384Speter error = userland_sysctl(td, name, uap->namelen, 1323100384Speter uap->old, &oldlen, 1, 1324136404Speter uap->new, uap->newlen, &j, SCTL_MASK32); 1325100384Speter if (error && error != ENOMEM) 1326100384Speter goto done2; 1327136404Speter if (uap->oldlenp) 1328100384Speter suword32(uap->oldlenp, j); 1329100384Speterdone2: 1330100384Speter mtx_unlock(&Giant); 1331100384Speter return (error); 1332100384Speter} 1333100384Speter 1334100384Speterstruct sigaction32 { 1335100384Speter u_int32_t sa_u; 1336100384Speter int sa_flags; 1337100384Speter sigset_t sa_mask; 1338100384Speter}; 1339100384Speter 1340121719SpeterCTASSERT(sizeof(struct sigaction32) == 24); 1341121719Speter 1342100384Speterint 1343119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap) 1344100384Speter{ 1345113859Sjhb struct sigaction32 s32; 1346113859Sjhb struct sigaction sa, osa, *sap; 1347100384Speter int error; 1348100384Speter 1349113859Sjhb if (uap->act) { 1350113859Sjhb error = copyin(uap->act, &s32, sizeof(s32)); 1351100384Speter if (error) 1352100384Speter return (error); 1353113859Sjhb sa.sa_handler = PTRIN(s32.sa_u); 1354113859Sjhb CP(s32, sa, sa_flags); 1355113859Sjhb CP(s32, sa, sa_mask); 1356113859Sjhb sap = &sa; 1357113859Sjhb } else 1358113859Sjhb sap = NULL; 1359113859Sjhb error = kern_sigaction(td, uap->sig, sap, &osa, 0); 1360146583Sps if (error == 0 && uap->oact != NULL) { 1361113859Sjhb s32.sa_u = PTROUT(osa.sa_handler); 1362113859Sjhb CP(osa, s32, sa_flags); 1363113859Sjhb CP(osa, s32, sa_mask); 1364113859Sjhb error = copyout(&s32, uap->oact, sizeof(s32)); 1365100384Speter } 1366100384Speter return (error); 1367100384Speter} 1368100384Speter 1369114987Speter#ifdef COMPAT_FREEBSD4 1370114987Speterint 1371119333Speterfreebsd4_freebsd32_sigaction(struct thread *td, 1372119333Speter struct freebsd4_freebsd32_sigaction_args *uap) 1373114987Speter{ 1374114987Speter struct sigaction32 s32; 1375114987Speter struct sigaction sa, osa, *sap; 1376114987Speter int error; 1377114987Speter 1378114987Speter if (uap->act) { 1379114987Speter error = copyin(uap->act, &s32, sizeof(s32)); 1380114987Speter if (error) 1381114987Speter return (error); 1382114987Speter sa.sa_handler = PTRIN(s32.sa_u); 1383114987Speter CP(s32, sa, sa_flags); 1384114987Speter CP(s32, sa, sa_mask); 1385114987Speter sap = &sa; 1386114987Speter } else 1387114987Speter sap = NULL; 1388114987Speter error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4); 1389146583Sps if (error == 0 && uap->oact != NULL) { 1390114987Speter s32.sa_u = PTROUT(osa.sa_handler); 1391114987Speter CP(osa, s32, sa_flags); 1392114987Speter CP(osa, s32, sa_mask); 1393114987Speter error = copyout(&s32, uap->oact, sizeof(s32)); 1394114987Speter } 1395114987Speter return (error); 1396114987Speter} 1397114987Speter#endif 1398114987Speter 1399151582Sps#ifdef COMPAT_43 1400151720Speterstruct osigaction32 { 1401151582Sps u_int32_t sa_u; 1402151582Sps osigset_t sa_mask; 1403151582Sps int sa_flags; 1404151582Sps}; 1405151582Sps 1406151582Sps#define ONSIG 32 1407151582Sps 1408140481Spsint 1409151720Speterofreebsd32_sigaction(struct thread *td, 1410151720Speter struct ofreebsd32_sigaction_args *uap) 1411151582Sps{ 1412151720Speter struct osigaction32 s32; 1413151582Sps struct sigaction sa, osa, *sap; 1414151582Sps int error; 1415151582Sps 1416151582Sps if (uap->signum <= 0 || uap->signum >= ONSIG) 1417151582Sps return (EINVAL); 1418151582Sps 1419151582Sps if (uap->nsa) { 1420151582Sps error = copyin(uap->nsa, &s32, sizeof(s32)); 1421151582Sps if (error) 1422151582Sps return (error); 1423151582Sps sa.sa_handler = PTRIN(s32.sa_u); 1424151582Sps CP(s32, sa, sa_flags); 1425151582Sps OSIG2SIG(s32.sa_mask, sa.sa_mask); 1426151582Sps sap = &sa; 1427151582Sps } else 1428151582Sps sap = NULL; 1429151582Sps error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET); 1430151582Sps if (error == 0 && uap->osa != NULL) { 1431151582Sps s32.sa_u = PTROUT(osa.sa_handler); 1432151582Sps CP(osa, s32, sa_flags); 1433151582Sps SIG2OSIG(osa.sa_mask, s32.sa_mask); 1434151582Sps error = copyout(&s32, uap->osa, sizeof(s32)); 1435151582Sps } 1436151582Sps return (error); 1437151582Sps} 1438151582Sps 1439151582Spsint 1440151720Speterofreebsd32_sigprocmask(struct thread *td, 1441151720Speter struct ofreebsd32_sigprocmask_args *uap) 1442151582Sps{ 1443151582Sps sigset_t set, oset; 1444151582Sps int error; 1445151582Sps 1446151582Sps OSIG2SIG(uap->mask, set); 1447151582Sps error = kern_sigprocmask(td, uap->how, &set, &oset, 1); 1448151582Sps SIG2OSIG(oset, td->td_retval[0]); 1449151582Sps return (error); 1450151582Sps} 1451151582Sps 1452151582Spsint 1453151720Speterofreebsd32_sigpending(struct thread *td, 1454151720Speter struct ofreebsd32_sigpending_args *uap) 1455151582Sps{ 1456151582Sps struct proc *p = td->td_proc; 1457151582Sps sigset_t siglist; 1458151582Sps 1459151582Sps PROC_LOCK(p); 1460151582Sps siglist = p->p_siglist; 1461151582Sps SIGSETOR(siglist, td->td_siglist); 1462151582Sps PROC_UNLOCK(p); 1463151582Sps SIG2OSIG(siglist, td->td_retval[0]); 1464151582Sps return (0); 1465151582Sps} 1466151582Sps 1467151582Spsstruct sigvec32 { 1468151582Sps u_int32_t sv_handler; 1469151582Sps int sv_mask; 1470151582Sps int sv_flags; 1471151582Sps}; 1472151582Sps 1473151582Spsint 1474151720Speterofreebsd32_sigvec(struct thread *td, 1475151720Speter struct ofreebsd32_sigvec_args *uap) 1476151582Sps{ 1477151582Sps struct sigvec32 vec; 1478151582Sps struct sigaction sa, osa, *sap; 1479151582Sps int error; 1480151582Sps 1481151582Sps if (uap->signum <= 0 || uap->signum >= ONSIG) 1482151582Sps return (EINVAL); 1483151582Sps 1484151582Sps if (uap->nsv) { 1485151582Sps error = copyin(uap->nsv, &vec, sizeof(vec)); 1486151582Sps if (error) 1487151582Sps return (error); 1488151582Sps sa.sa_handler = PTRIN(vec.sv_handler); 1489151582Sps OSIG2SIG(vec.sv_mask, sa.sa_mask); 1490151582Sps sa.sa_flags = vec.sv_flags; 1491151582Sps sa.sa_flags ^= SA_RESTART; 1492151582Sps sap = &sa; 1493151582Sps } else 1494151582Sps sap = NULL; 1495151582Sps error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET); 1496151582Sps if (error == 0 && uap->osv != NULL) { 1497151582Sps vec.sv_handler = PTROUT(osa.sa_handler); 1498151582Sps SIG2OSIG(osa.sa_mask, vec.sv_mask); 1499151582Sps vec.sv_flags = osa.sa_flags; 1500151582Sps vec.sv_flags &= ~SA_NOCLDWAIT; 1501151582Sps vec.sv_flags ^= SA_RESTART; 1502151582Sps error = copyout(&vec, uap->osv, sizeof(vec)); 1503151582Sps } 1504151582Sps return (error); 1505151582Sps} 1506151582Sps 1507151582Spsint 1508151720Speterofreebsd32_sigblock(struct thread *td, 1509151720Speter struct ofreebsd32_sigblock_args *uap) 1510151582Sps{ 1511151582Sps struct proc *p = td->td_proc; 1512151582Sps sigset_t set; 1513151582Sps 1514151582Sps OSIG2SIG(uap->mask, set); 1515151582Sps SIG_CANTMASK(set); 1516151582Sps PROC_LOCK(p); 1517151582Sps SIG2OSIG(td->td_sigmask, td->td_retval[0]); 1518151582Sps SIGSETOR(td->td_sigmask, set); 1519151582Sps PROC_UNLOCK(p); 1520151582Sps return (0); 1521151582Sps} 1522151582Sps 1523151582Spsint 1524151720Speterofreebsd32_sigsetmask(struct thread *td, 1525151720Speter struct ofreebsd32_sigsetmask_args *uap) 1526151582Sps{ 1527151582Sps struct proc *p = td->td_proc; 1528151582Sps sigset_t set; 1529151582Sps 1530151582Sps OSIG2SIG(uap->mask, set); 1531151582Sps SIG_CANTMASK(set); 1532151582Sps PROC_LOCK(p); 1533151582Sps SIG2OSIG(td->td_sigmask, td->td_retval[0]); 1534151582Sps SIGSETLO(td->td_sigmask, set); 1535151582Sps signotify(td); 1536151582Sps PROC_UNLOCK(p); 1537151582Sps return (0); 1538151582Sps} 1539151582Sps 1540151582Spsint 1541151720Speterofreebsd32_sigsuspend(struct thread *td, 1542151720Speter struct ofreebsd32_sigsuspend_args *uap) 1543151582Sps{ 1544151582Sps struct proc *p = td->td_proc; 1545151582Sps sigset_t mask; 1546151582Sps 1547151582Sps PROC_LOCK(p); 1548151582Sps td->td_oldsigmask = td->td_sigmask; 1549151582Sps td->td_pflags |= TDP_OLDMASK; 1550151582Sps OSIG2SIG(uap->mask, mask); 1551151582Sps SIG_CANTMASK(mask); 1552151582Sps SIGSETLO(td->td_sigmask, mask); 1553151582Sps signotify(td); 1554151582Sps while (msleep(&p->p_sigacts, &p->p_mtx, PPAUSE|PCATCH, "opause", 0) == 0) 1555151582Sps /* void */; 1556151582Sps PROC_UNLOCK(p); 1557151582Sps /* always return EINTR rather than ERESTART... */ 1558151582Sps return (EINTR); 1559151582Sps} 1560151582Sps 1561151582Spsstruct sigstack32 { 1562151582Sps u_int32_t ss_sp; 1563151582Sps int ss_onstack; 1564151582Sps}; 1565151582Sps 1566151582Spsint 1567151720Speterofreebsd32_sigstack(struct thread *td, 1568151720Speter struct ofreebsd32_sigstack_args *uap) 1569151582Sps{ 1570151582Sps struct sigstack32 s32; 1571151582Sps struct sigstack nss, oss; 1572151582Sps int error = 0; 1573151582Sps 1574151582Sps if (uap->nss != NULL) { 1575151582Sps error = copyin(uap->nss, &s32, sizeof(s32)); 1576151582Sps if (error) 1577151582Sps return (error); 1578151582Sps nss.ss_sp = PTRIN(s32.ss_sp); 1579151582Sps CP(s32, nss, ss_onstack); 1580151582Sps } 1581151582Sps oss.ss_sp = td->td_sigstk.ss_sp; 1582151582Sps oss.ss_onstack = sigonstack(cpu_getstack(td)); 1583151582Sps if (uap->nss != NULL) { 1584151582Sps td->td_sigstk.ss_sp = nss.ss_sp; 1585151582Sps td->td_sigstk.ss_size = 0; 1586151582Sps td->td_sigstk.ss_flags |= nss.ss_onstack & SS_ONSTACK; 1587151582Sps td->td_pflags |= TDP_ALTSTACK; 1588151582Sps } 1589151582Sps if (uap->oss != NULL) { 1590151582Sps s32.ss_sp = PTROUT(oss.ss_sp); 1591151582Sps CP(oss, s32, ss_onstack); 1592151582Sps error = copyout(&s32, uap->oss, sizeof(s32)); 1593151582Sps } 1594151582Sps return (error); 1595151582Sps} 1596151582Sps#endif 1597151582Sps 1598151582Spsint 1599140481Spsfreebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap) 1600140481Sps{ 1601140481Sps struct timespec32 rmt32, rqt32; 1602140481Sps struct timespec rmt, rqt; 1603140481Sps int error; 1604140481Sps 1605151355Sps error = copyin(uap->rqtp, &rqt32, sizeof(rqt32)); 1606140481Sps if (error) 1607140481Sps return (error); 1608140481Sps 1609140481Sps CP(rqt32, rqt, tv_sec); 1610140481Sps CP(rqt32, rqt, tv_nsec); 1611140481Sps 1612140481Sps if (uap->rmtp && 1613140481Sps !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE)) 1614140481Sps return (EFAULT); 1615140481Sps error = kern_nanosleep(td, &rqt, &rmt); 1616140481Sps if (error && uap->rmtp) { 1617140481Sps int error2; 1618140481Sps 1619140481Sps CP(rmt, rmt32, tv_sec); 1620140481Sps CP(rmt, rmt32, tv_nsec); 1621140481Sps 1622151355Sps error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt32)); 1623140481Sps if (error2) 1624140481Sps error = error2; 1625140481Sps } 1626140481Sps return (error); 1627140481Sps} 1628140481Sps 1629151357Spsint 1630151357Spsfreebsd32_clock_gettime(struct thread *td, 1631151357Sps struct freebsd32_clock_gettime_args *uap) 1632151357Sps{ 1633151357Sps struct timespec ats; 1634151357Sps struct timespec32 ats32; 1635151357Sps int error; 1636151357Sps 1637151357Sps error = kern_clock_gettime(td, uap->clock_id, &ats); 1638151357Sps if (error == 0) { 1639151357Sps CP(ats, ats32, tv_sec); 1640151357Sps CP(ats, ats32, tv_nsec); 1641151357Sps error = copyout(&ats32, uap->tp, sizeof(ats32)); 1642151357Sps } 1643151357Sps return (error); 1644151357Sps} 1645151357Sps 1646151357Spsint 1647151357Spsfreebsd32_clock_settime(struct thread *td, 1648151357Sps struct freebsd32_clock_settime_args *uap) 1649151357Sps{ 1650151357Sps struct timespec ats; 1651151357Sps struct timespec32 ats32; 1652151357Sps int error; 1653151357Sps 1654151357Sps error = copyin(uap->tp, &ats32, sizeof(ats32)); 1655151357Sps if (error) 1656151357Sps return (error); 1657151357Sps CP(ats32, ats, tv_sec); 1658151357Sps CP(ats32, ats, tv_nsec); 1659151357Sps 1660151357Sps return (kern_clock_settime(td, uap->clock_id, &ats)); 1661151357Sps} 1662151357Sps 1663151357Spsint 1664151357Spsfreebsd32_clock_getres(struct thread *td, 1665151357Sps struct freebsd32_clock_getres_args *uap) 1666151357Sps{ 1667151357Sps struct timespec ts; 1668151357Sps struct timespec32 ts32; 1669151357Sps int error; 1670151357Sps 1671151357Sps if (uap->tp == NULL) 1672151357Sps return (0); 1673151357Sps error = kern_clock_getres(td, uap->clock_id, &ts); 1674151357Sps if (error == 0) { 1675151357Sps CP(ts, ts32, tv_sec); 1676151357Sps CP(ts, ts32, tv_nsec); 1677151357Sps error = copyout(&ts32, uap->tp, sizeof(ts32)); 1678151357Sps } 1679151357Sps return (error); 1680151357Sps} 1681151357Sps 1682100384Speter#if 0 1683100384Speter 1684100384Speterint 1685119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) 1686100384Speter{ 1687100384Speter int error; 1688100384Speter struct yyy32 *p32, s32; 1689100384Speter struct yyy *p = NULL, s; 1690100384Speter 1691147654Sjhb if (uap->zzz) { 1692147654Sjhb error = copyin(uap->zzz, &s32, sizeof(s32)); 1693100384Speter if (error) 1694100384Speter return (error); 1695100384Speter /* translate in */ 1696147654Sjhb p = &s; 1697100384Speter } 1698147654Sjhb error = kern_xxx(td, p); 1699100384Speter if (error) 1700100384Speter return (error); 1701147654Sjhb if (uap->zzz) { 1702100384Speter /* translate out */ 1703100384Speter error = copyout(&s32, p32, sizeof(s32)); 1704100384Speter } 1705100384Speter return (error); 1706100384Speter} 1707100384Speter 1708100384Speter#endif 1709