freebsd32_misc.c revision 151909
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 151909 2005-10-31 21:09:56Z ps $"); 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> 72100384Speter 73100384Speter#include <vm/vm.h> 74100384Speter#include <vm/vm_kern.h> 75100384Speter#include <vm/vm_param.h> 76100384Speter#include <vm/pmap.h> 77100384Speter#include <vm/vm_map.h> 78100384Speter#include <vm/vm_object.h> 79100384Speter#include <vm/vm_extern.h> 80100384Speter 81151582Sps#include <machine/cpu.h> 82151582Sps 83119333Speter#include <compat/freebsd32/freebsd32_util.h> 84119333Speter#include <compat/freebsd32/freebsd32.h> 85119333Speter#include <compat/freebsd32/freebsd32_proto.h> 86100384Speter 87121719SpeterCTASSERT(sizeof(struct timeval32) == 8); 88121719SpeterCTASSERT(sizeof(struct timespec32) == 8); 89121719SpeterCTASSERT(sizeof(struct statfs32) == 256); 90121719SpeterCTASSERT(sizeof(struct rusage32) == 72); 91121719Speter 92100384Speterint 93119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) 94100384Speter{ 95127140Sjhb int error, status; 96127140Sjhb struct rusage32 ru32; 97136152Sjhb struct rusage ru, *rup; 98100384Speter 99136152Sjhb if (uap->rusage != NULL) 100136152Sjhb rup = &ru; 101136152Sjhb else 102136152Sjhb rup = NULL; 103136152Sjhb error = kern_wait(td, uap->pid, &status, uap->options, rup); 104100384Speter if (error) 105100384Speter return (error); 106127140Sjhb if (uap->status != NULL) 107127140Sjhb error = copyout(&status, uap->status, sizeof(status)); 108127140Sjhb if (uap->rusage != NULL && error == 0) { 109100384Speter TV_CP(ru, ru32, ru_utime); 110100384Speter TV_CP(ru, ru32, ru_stime); 111100384Speter CP(ru, ru32, ru_maxrss); 112100384Speter CP(ru, ru32, ru_ixrss); 113100384Speter CP(ru, ru32, ru_idrss); 114100384Speter CP(ru, ru32, ru_isrss); 115100384Speter CP(ru, ru32, ru_minflt); 116100384Speter CP(ru, ru32, ru_majflt); 117100384Speter CP(ru, ru32, ru_nswap); 118100384Speter CP(ru, ru32, ru_inblock); 119100384Speter CP(ru, ru32, ru_oublock); 120100384Speter CP(ru, ru32, ru_msgsnd); 121100384Speter CP(ru, ru32, ru_msgrcv); 122100384Speter CP(ru, ru32, ru_nsignals); 123100384Speter CP(ru, ru32, ru_nvcsw); 124100384Speter CP(ru, ru32, ru_nivcsw); 125127140Sjhb error = copyout(&ru32, uap->rusage, sizeof(ru32)); 126100384Speter } 127100384Speter return (error); 128100384Speter} 129100384Speter 130128597Smarcel#ifdef COMPAT_FREEBSD4 131100384Speterstatic void 132100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out) 133100384Speter{ 134100384Speter CP(*in, *out, f_bsize); 135100384Speter CP(*in, *out, f_iosize); 136100384Speter CP(*in, *out, f_blocks); 137100384Speter CP(*in, *out, f_bfree); 138100384Speter CP(*in, *out, f_bavail); 139100384Speter CP(*in, *out, f_files); 140100384Speter CP(*in, *out, f_ffree); 141100384Speter CP(*in, *out, f_fsid); 142100384Speter CP(*in, *out, f_owner); 143100384Speter CP(*in, *out, f_type); 144100384Speter CP(*in, *out, f_flags); 145100384Speter CP(*in, *out, f_flags); 146100384Speter CP(*in, *out, f_syncwrites); 147100384Speter CP(*in, *out, f_asyncwrites); 148100384Speter bcopy(in->f_fstypename, 149100384Speter out->f_fstypename, MFSNAMELEN); 150100384Speter bcopy(in->f_mntonname, 151128260Speter out->f_mntonname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 152100384Speter CP(*in, *out, f_syncreads); 153100384Speter CP(*in, *out, f_asyncreads); 154100384Speter bcopy(in->f_mntfromname, 155128260Speter out->f_mntfromname, min(MNAMELEN, FREEBSD4_MNAMELEN)); 156100384Speter} 157128597Smarcel#endif 158100384Speter 159128597Smarcel#ifdef COMPAT_FREEBSD4 160100384Speterint 161128260Speterfreebsd4_freebsd32_getfsstat(struct thread *td, struct freebsd4_freebsd32_getfsstat_args *uap) 162100384Speter{ 163147178Spjd struct statfs *buf, *sp; 164147178Spjd struct statfs32 stat32; 165147178Spjd size_t count, size; 166100384Speter int error; 167100384Speter 168147178Spjd count = uap->bufsize / sizeof(struct statfs32); 169147178Spjd size = count * sizeof(struct statfs); 170147302Spjd error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags); 171147302Spjd if (size > 0) { 172100384Speter count = td->td_retval[0]; 173147178Spjd sp = buf; 174147178Spjd while (count > 0 && error == 0) { 175147178Spjd copy_statfs(sp, &stat32); 176147178Spjd error = copyout(&stat32, uap->buf, sizeof(stat32)); 177147178Spjd sp++; 178147178Spjd uap->buf++; 179147178Spjd count--; 180100384Speter } 181147178Spjd free(buf, M_TEMP); 182100384Speter } 183100384Speter return (error); 184100384Speter} 185128597Smarcel#endif 186100384Speter 187100384Speterstruct sigaltstack32 { 188100384Speter u_int32_t ss_sp; 189100384Speter u_int32_t ss_size; 190100384Speter int ss_flags; 191100384Speter}; 192100384Speter 193121719SpeterCTASSERT(sizeof(struct sigaltstack32) == 12); 194121719Speter 195100384Speterint 196119333Speterfreebsd32_sigaltstack(struct thread *td, 197119333Speter struct freebsd32_sigaltstack_args *uap) 198100384Speter{ 199113859Sjhb struct sigaltstack32 s32; 200113859Sjhb struct sigaltstack ss, oss, *ssp; 201100384Speter int error; 202100384Speter 203113859Sjhb if (uap->ss != NULL) { 204113859Sjhb error = copyin(uap->ss, &s32, sizeof(s32)); 205100384Speter if (error) 206100384Speter return (error); 207113859Sjhb PTRIN_CP(s32, ss, ss_sp); 208113859Sjhb CP(s32, ss, ss_size); 209113859Sjhb CP(s32, ss, ss_flags); 210113859Sjhb ssp = &ss; 211113859Sjhb } else 212113859Sjhb ssp = NULL; 213113859Sjhb error = kern_sigaltstack(td, ssp, &oss); 214113859Sjhb if (error == 0 && uap->oss != NULL) { 215113859Sjhb PTROUT_CP(oss, s32, ss_sp); 216113859Sjhb CP(oss, s32, ss_size); 217113859Sjhb CP(oss, s32, ss_flags); 218113859Sjhb error = copyout(&s32, uap->oss, sizeof(s32)); 219100384Speter } 220100384Speter return (error); 221100384Speter} 222100384Speter 223142059Sjhb/* 224142059Sjhb * Custom version of exec_copyin_args() so that we can translate 225142059Sjhb * the pointers. 226142059Sjhb */ 227142059Sjhbstatic int 228142059Sjhbfreebsd32_exec_copyin_args(struct image_args *args, char *fname, 229142059Sjhb enum uio_seg segflg, u_int32_t *argv, u_int32_t *envv) 230100384Speter{ 231142059Sjhb char *argp, *envp; 232142059Sjhb u_int32_t *p32, arg; 233142059Sjhb size_t length; 234100384Speter int error; 235100384Speter 236142059Sjhb bzero(args, sizeof(*args)); 237142059Sjhb if (argv == NULL) 238142059Sjhb return (EFAULT); 239100384Speter 240142059Sjhb /* 241142059Sjhb * Allocate temporary demand zeroed space for argument and 242142059Sjhb * environment strings 243142059Sjhb */ 244147588Sjhb args->buf = (char *) kmem_alloc_wait(exec_map, 245147588Sjhb PATH_MAX + ARG_MAX + MAXSHELLCMDLEN); 246142059Sjhb if (args->buf == NULL) 247142059Sjhb return (ENOMEM); 248142059Sjhb args->begin_argv = args->buf; 249142059Sjhb args->endp = args->begin_argv; 250142059Sjhb args->stringspace = ARG_MAX; 251142059Sjhb 252142059Sjhb args->fname = args->buf + ARG_MAX; 253142059Sjhb 254142059Sjhb /* 255142059Sjhb * Copy the file name. 256142059Sjhb */ 257142059Sjhb error = (segflg == UIO_SYSSPACE) ? 258142059Sjhb copystr(fname, args->fname, PATH_MAX, &length) : 259142059Sjhb copyinstr(fname, args->fname, PATH_MAX, &length); 260142059Sjhb if (error != 0) 261142059Sjhb return (error); 262142059Sjhb 263142059Sjhb /* 264142059Sjhb * extract arguments first 265142059Sjhb */ 266142059Sjhb p32 = argv; 267142059Sjhb for (;;) { 268142059Sjhb error = copyin(p32++, &arg, sizeof(arg)); 269142059Sjhb if (error) 270142059Sjhb return (error); 271142059Sjhb if (arg == 0) 272142059Sjhb break; 273142059Sjhb argp = PTRIN(arg); 274142059Sjhb error = copyinstr(argp, args->endp, args->stringspace, &length); 275142059Sjhb if (error) { 276142059Sjhb if (error == ENAMETOOLONG) 277142059Sjhb return (E2BIG); 278142059Sjhb else 279142059Sjhb return (error); 280142059Sjhb } 281142059Sjhb args->stringspace -= length; 282142059Sjhb args->endp += length; 283142059Sjhb args->argc++; 284100384Speter } 285142059Sjhb 286142059Sjhb args->begin_envv = args->endp; 287142059Sjhb 288142059Sjhb /* 289142059Sjhb * extract environment strings 290142059Sjhb */ 291142059Sjhb if (envv) { 292142059Sjhb p32 = envv; 293142059Sjhb for (;;) { 294100384Speter error = copyin(p32++, &arg, sizeof(arg)); 295100384Speter if (error) 296142059Sjhb return (error); 297142059Sjhb if (arg == 0) 298142059Sjhb break; 299142059Sjhb envp = PTRIN(arg); 300142059Sjhb error = copyinstr(envp, args->endp, args->stringspace, 301142059Sjhb &length); 302142059Sjhb if (error) { 303142059Sjhb if (error == ENAMETOOLONG) 304142059Sjhb return (E2BIG); 305142059Sjhb else 306142059Sjhb return (error); 307142059Sjhb } 308142059Sjhb args->stringspace -= length; 309142059Sjhb args->endp += length; 310142059Sjhb args->envc++; 311142059Sjhb } 312100384Speter } 313100384Speter 314142059Sjhb return (0); 315100384Speter} 316100384Speter 317142059Sjhbint 318142059Sjhbfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) 319142059Sjhb{ 320142059Sjhb struct image_args eargs; 321142059Sjhb int error; 322142059Sjhb 323142059Sjhb error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE, 324142059Sjhb uap->argv, uap->envv); 325142059Sjhb if (error == 0) 326142059Sjhb error = kern_execve(td, &eargs, NULL); 327142059Sjhb exec_free_args(&eargs); 328142059Sjhb return (error); 329142059Sjhb} 330142059Sjhb 331114987Speter#ifdef __ia64__ 332100384Speterstatic int 333119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 334119333Speter int prot, int fd, off_t pos) 335100384Speter{ 336100384Speter vm_map_t map; 337100384Speter vm_map_entry_t entry; 338100384Speter int rv; 339100384Speter 340100384Speter map = &td->td_proc->p_vmspace->vm_map; 341100384Speter if (fd != -1) 342100384Speter prot |= VM_PROT_WRITE; 343100384Speter 344100384Speter if (vm_map_lookup_entry(map, start, &entry)) { 345100384Speter if ((entry->protection & prot) != prot) { 346100384Speter rv = vm_map_protect(map, 347100384Speter trunc_page(start), 348100384Speter round_page(end), 349100384Speter entry->protection | prot, 350100384Speter FALSE); 351100384Speter if (rv != KERN_SUCCESS) 352100384Speter return (EINVAL); 353100384Speter } 354100384Speter } else { 355100384Speter vm_offset_t addr = trunc_page(start); 356100384Speter rv = vm_map_find(map, 0, 0, 357100384Speter &addr, PAGE_SIZE, FALSE, prot, 358100384Speter VM_PROT_ALL, 0); 359100384Speter if (rv != KERN_SUCCESS) 360100384Speter return (EINVAL); 361100384Speter } 362100384Speter 363100384Speter if (fd != -1) { 364100384Speter struct pread_args r; 365107849Salfred r.fd = fd; 366107849Salfred r.buf = (void *) start; 367107849Salfred r.nbyte = end - start; 368107849Salfred r.offset = pos; 369100384Speter return (pread(td, &r)); 370100384Speter } else { 371100384Speter while (start < end) { 372100384Speter subyte((void *) start, 0); 373100384Speter start++; 374100384Speter } 375100384Speter return (0); 376100384Speter } 377100384Speter} 378114987Speter#endif 379100384Speter 380100384Speterint 381119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) 382100384Speter{ 383100384Speter struct mmap_args ap; 384107849Salfred vm_offset_t addr = (vm_offset_t) uap->addr; 385107849Salfred vm_size_t len = uap->len; 386107849Salfred int prot = uap->prot; 387107849Salfred int flags = uap->flags; 388107849Salfred int fd = uap->fd; 389107849Salfred off_t pos = (uap->poslo 390107849Salfred | ((off_t)uap->poshi << 32)); 391114987Speter#ifdef __ia64__ 392100384Speter vm_size_t pageoff; 393100384Speter int error; 394100384Speter 395100384Speter /* 396100384Speter * Attempt to handle page size hassles. 397100384Speter */ 398100384Speter pageoff = (pos & PAGE_MASK); 399100384Speter if (flags & MAP_FIXED) { 400100384Speter vm_offset_t start, end; 401100384Speter start = addr; 402100384Speter end = addr + len; 403100384Speter 404147964Sjhb mtx_lock(&Giant); 405100384Speter if (start != trunc_page(start)) { 406119333Speter error = freebsd32_mmap_partial(td, start, 407119333Speter round_page(start), prot, 408119333Speter fd, pos); 409100384Speter if (fd != -1) 410100384Speter pos += round_page(start) - start; 411100384Speter start = round_page(start); 412100384Speter } 413100384Speter if (end != round_page(end)) { 414100384Speter vm_offset_t t = trunc_page(end); 415119333Speter error = freebsd32_mmap_partial(td, t, end, 416100384Speter prot, fd, 417100384Speter pos + t - start); 418100384Speter end = trunc_page(end); 419100384Speter } 420100384Speter if (end > start && fd != -1 && (pos & PAGE_MASK)) { 421100384Speter /* 422100384Speter * We can't map this region at all. The specified 423100384Speter * address doesn't have the same alignment as the file 424100384Speter * position. Fake the mapping by simply reading the 425100384Speter * entire region into memory. First we need to make 426100384Speter * sure the region exists. 427100384Speter */ 428100384Speter vm_map_t map; 429100384Speter struct pread_args r; 430100384Speter int rv; 431100384Speter 432100384Speter prot |= VM_PROT_WRITE; 433100384Speter map = &td->td_proc->p_vmspace->vm_map; 434100384Speter rv = vm_map_remove(map, start, end); 435147964Sjhb if (rv != KERN_SUCCESS) { 436147964Sjhb mtx_unlock(&Giant); 437100384Speter return (EINVAL); 438147964Sjhb } 439100384Speter rv = vm_map_find(map, 0, 0, 440100384Speter &start, end - start, FALSE, 441100384Speter prot, VM_PROT_ALL, 0); 442147964Sjhb mtx_unlock(&Giant); 443100384Speter if (rv != KERN_SUCCESS) 444100384Speter return (EINVAL); 445107849Salfred r.fd = fd; 446107849Salfred r.buf = (void *) start; 447107849Salfred r.nbyte = end - start; 448107849Salfred r.offset = pos; 449100384Speter error = pread(td, &r); 450100384Speter if (error) 451100384Speter return (error); 452100384Speter 453100384Speter td->td_retval[0] = addr; 454100384Speter return (0); 455100384Speter } 456147964Sjhb mtx_unlock(&Giant); 457100384Speter if (end == start) { 458100384Speter /* 459100384Speter * After dealing with the ragged ends, there 460100384Speter * might be none left. 461100384Speter */ 462100384Speter td->td_retval[0] = addr; 463100384Speter return (0); 464100384Speter } 465100384Speter addr = start; 466100384Speter len = end - start; 467100384Speter } 468114987Speter#endif 469100384Speter 470107849Salfred ap.addr = (void *) addr; 471107849Salfred ap.len = len; 472107849Salfred ap.prot = prot; 473107849Salfred ap.flags = flags; 474107849Salfred ap.fd = fd; 475107849Salfred ap.pos = pos; 476100384Speter 477100384Speter return (mmap(td, &ap)); 478100384Speter} 479100384Speter 480100384Speterstruct itimerval32 { 481100384Speter struct timeval32 it_interval; 482100384Speter struct timeval32 it_value; 483100384Speter}; 484100384Speter 485121719SpeterCTASSERT(sizeof(struct itimerval32) == 16); 486121719Speter 487100384Speterint 488119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap) 489100384Speter{ 490142059Sjhb struct itimerval itv, oitv, *itvp; 491142059Sjhb struct itimerval32 i32; 492100384Speter int error; 493100384Speter 494142059Sjhb if (uap->itv != NULL) { 495142059Sjhb error = copyin(uap->itv, &i32, sizeof(i32)); 496100384Speter if (error) 497100384Speter return (error); 498142059Sjhb TV_CP(i32, itv, it_interval); 499142059Sjhb TV_CP(i32, itv, it_value); 500142059Sjhb itvp = &itv; 501142059Sjhb } else 502142059Sjhb itvp = NULL; 503142059Sjhb error = kern_setitimer(td, uap->which, itvp, &oitv); 504142059Sjhb if (error || uap->oitv == NULL) 505100384Speter return (error); 506142059Sjhb TV_CP(oitv, i32, it_interval); 507142059Sjhb TV_CP(oitv, i32, it_value); 508142059Sjhb return (copyout(&i32, uap->oitv, sizeof(i32))); 509100384Speter} 510100384Speter 511100384Speterint 512125171Speterfreebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap) 513125171Speter{ 514142059Sjhb struct itimerval itv; 515142059Sjhb struct itimerval32 i32; 516125171Speter int error; 517125171Speter 518142059Sjhb error = kern_getitimer(td, uap->which, &itv); 519142059Sjhb if (error || uap->itv == NULL) 520125171Speter return (error); 521142059Sjhb TV_CP(itv, i32, it_interval); 522142059Sjhb TV_CP(itv, i32, it_value); 523142059Sjhb return (copyout(&i32, uap->itv, sizeof(i32))); 524125171Speter} 525125171Speter 526125171Speterint 527119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap) 528100384Speter{ 529142059Sjhb struct timeval32 tv32; 530142059Sjhb struct timeval tv, *tvp; 531100384Speter int error; 532100384Speter 533142059Sjhb if (uap->tv != NULL) { 534142059Sjhb error = copyin(uap->tv, &tv32, sizeof(tv32)); 535100384Speter if (error) 536100384Speter return (error); 537142059Sjhb CP(tv32, tv, tv_sec); 538142059Sjhb CP(tv32, tv, tv_usec); 539142059Sjhb tvp = &tv; 540142059Sjhb } else 541142059Sjhb tvp = NULL; 542100384Speter /* 543100384Speter * XXX big-endian needs to convert the fd_sets too. 544142059Sjhb * XXX Do pointers need PTRIN()? 545100384Speter */ 546142059Sjhb return (kern_select(td, uap->nd, uap->in, uap->ou, uap->ex, tvp)); 547100384Speter} 548100384Speter 549114987Speterstruct kevent32 { 550114987Speter u_int32_t ident; /* identifier for this event */ 551114987Speter short filter; /* filter for event */ 552114987Speter u_short flags; 553114987Speter u_int fflags; 554114987Speter int32_t data; 555114987Speter u_int32_t udata; /* opaque user data identifier */ 556114987Speter}; 557114987Speter 558121719SpeterCTASSERT(sizeof(struct kevent32) == 20); 559146950Spsstatic int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count); 560146950Spsstatic int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count); 561121719Speter 562146950Sps/* 563146950Sps * Copy 'count' items into the destination list pointed to by uap->eventlist. 564146950Sps */ 565146950Spsstatic int 566146950Spsfreebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count) 567146950Sps{ 568146950Sps struct freebsd32_kevent_args *uap; 569146950Sps struct kevent32 ks32[KQ_NEVENTS]; 570146950Sps int i, error = 0; 571146950Sps 572146950Sps KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count)); 573146950Sps uap = (struct freebsd32_kevent_args *)arg; 574146950Sps 575146950Sps for (i = 0; i < count; i++) { 576146950Sps CP(kevp[i], ks32[i], ident); 577146950Sps CP(kevp[i], ks32[i], filter); 578146950Sps CP(kevp[i], ks32[i], flags); 579146950Sps CP(kevp[i], ks32[i], fflags); 580146950Sps CP(kevp[i], ks32[i], data); 581146950Sps PTROUT_CP(kevp[i], ks32[i], udata); 582146950Sps } 583146950Sps error = copyout(ks32, uap->eventlist, count * sizeof *ks32); 584146950Sps if (error == 0) 585146950Sps uap->eventlist += count; 586146950Sps return (error); 587146950Sps} 588146950Sps 589146950Sps/* 590146950Sps * Copy 'count' items from the list pointed to by uap->changelist. 591146950Sps */ 592146950Spsstatic int 593146950Spsfreebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count) 594146950Sps{ 595146950Sps struct freebsd32_kevent_args *uap; 596146950Sps struct kevent32 ks32[KQ_NEVENTS]; 597146950Sps int i, error = 0; 598146950Sps 599146950Sps KASSERT(count <= KQ_NEVENTS, ("count (%d) > KQ_NEVENTS", count)); 600146950Sps uap = (struct freebsd32_kevent_args *)arg; 601146950Sps 602146950Sps error = copyin(uap->changelist, ks32, count * sizeof *ks32); 603146950Sps if (error) 604146950Sps goto done; 605146950Sps uap->changelist += count; 606146950Sps 607146950Sps for (i = 0; i < count; i++) { 608146950Sps CP(ks32[i], kevp[i], ident); 609146950Sps CP(ks32[i], kevp[i], filter); 610146950Sps CP(ks32[i], kevp[i], flags); 611146950Sps CP(ks32[i], kevp[i], fflags); 612146950Sps CP(ks32[i], kevp[i], data); 613146950Sps PTRIN_CP(ks32[i], kevp[i], udata); 614146950Sps } 615146950Spsdone: 616146950Sps return (error); 617146950Sps} 618146950Sps 619100384Speterint 620119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap) 621114987Speter{ 622114987Speter struct timespec32 ts32; 623142934Sps struct timespec ts, *tsp; 624146950Sps struct kevent_copyops k_ops = { uap, 625146950Sps freebsd32_kevent_copyout, 626146950Sps freebsd32_kevent_copyin}; 627146950Sps int error; 628114987Speter 629114987Speter 630114987Speter if (uap->timeout) { 631114987Speter error = copyin(uap->timeout, &ts32, sizeof(ts32)); 632114987Speter if (error) 633114987Speter return (error); 634114987Speter CP(ts32, ts, tv_sec); 635114987Speter CP(ts32, ts, tv_nsec); 636142934Sps tsp = &ts; 637142934Sps } else 638142934Sps tsp = NULL; 639146950Sps error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents, 640146950Sps &k_ops, tsp); 641142934Sps return (error); 642114987Speter} 643114987Speter 644114987Speterint 645119333Speterfreebsd32_gettimeofday(struct thread *td, 646119333Speter struct freebsd32_gettimeofday_args *uap) 647100384Speter{ 648123425Speter struct timeval atv; 649123425Speter struct timeval32 atv32; 650123425Speter struct timezone rtz; 651123425Speter int error = 0; 652100384Speter 653123425Speter if (uap->tp) { 654123425Speter microtime(&atv); 655123425Speter CP(atv, atv32, tv_sec); 656123425Speter CP(atv, atv32, tv_usec); 657123425Speter error = copyout(&atv32, uap->tp, sizeof (atv32)); 658100384Speter } 659123425Speter if (error == 0 && uap->tzp != NULL) { 660123425Speter rtz.tz_minuteswest = tz_minuteswest; 661123425Speter rtz.tz_dsttime = tz_dsttime; 662123425Speter error = copyout(&rtz, uap->tzp, sizeof (rtz)); 663100384Speter } 664100384Speter return (error); 665100384Speter} 666100384Speter 667100384Speterint 668119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap) 669100384Speter{ 670136152Sjhb struct rusage32 s32; 671136152Sjhb struct rusage s; 672100384Speter int error; 673100384Speter 674136152Sjhb error = kern_getrusage(td, uap->who, &s); 675100384Speter if (error) 676100384Speter return (error); 677136152Sjhb if (uap->rusage != NULL) { 678100384Speter TV_CP(s, s32, ru_utime); 679100384Speter TV_CP(s, s32, ru_stime); 680100384Speter CP(s, s32, ru_maxrss); 681100384Speter CP(s, s32, ru_ixrss); 682100384Speter CP(s, s32, ru_idrss); 683100384Speter CP(s, s32, ru_isrss); 684100384Speter CP(s, s32, ru_minflt); 685100384Speter CP(s, s32, ru_majflt); 686100384Speter CP(s, s32, ru_nswap); 687100384Speter CP(s, s32, ru_inblock); 688100384Speter CP(s, s32, ru_oublock); 689100384Speter CP(s, s32, ru_msgsnd); 690100384Speter CP(s, s32, ru_msgrcv); 691100384Speter CP(s, s32, ru_nsignals); 692100384Speter CP(s, s32, ru_nvcsw); 693100384Speter CP(s, s32, ru_nivcsw); 694136152Sjhb error = copyout(&s32, uap->rusage, sizeof(s32)); 695100384Speter } 696100384Speter return (error); 697100384Speter} 698100384Speter 699100384Speterstruct iovec32 { 700100384Speter u_int32_t iov_base; 701100384Speter int iov_len; 702100384Speter}; 703100384Speter 704121719SpeterCTASSERT(sizeof(struct iovec32) == 8); 705121719Speter 706144450Sjhbstatic int 707144450Sjhbfreebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop) 708100384Speter{ 709144450Sjhb struct iovec32 iov32; 710144450Sjhb struct iovec *iov; 711144450Sjhb struct uio *uio; 712144450Sjhb u_int iovlen; 713144450Sjhb int error, i; 714100384Speter 715144450Sjhb *uiop = NULL; 716144450Sjhb if (iovcnt > UIO_MAXIOV) 717100384Speter return (EINVAL); 718144450Sjhb iovlen = iovcnt * sizeof(struct iovec); 719144450Sjhb uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK); 720144450Sjhb iov = (struct iovec *)(uio + 1); 721144450Sjhb for (i = 0; i < iovcnt; i++) { 722144450Sjhb error = copyin(&iovp[i], &iov32, sizeof(struct iovec32)); 723144450Sjhb if (error) { 724144450Sjhb free(uio, M_IOV); 725144450Sjhb return (error); 726144450Sjhb } 727144450Sjhb iov[i].iov_base = PTRIN(iov32.iov_base); 728144450Sjhb iov[i].iov_len = iov32.iov_len; 729100384Speter } 730144450Sjhb uio->uio_iov = iov; 731144450Sjhb uio->uio_iovcnt = iovcnt; 732144450Sjhb uio->uio_segflg = UIO_USERSPACE; 733144450Sjhb uio->uio_offset = -1; 734144450Sjhb uio->uio_resid = 0; 735144450Sjhb for (i = 0; i < iovcnt; i++) { 736144450Sjhb if (iov->iov_len > INT_MAX - uio->uio_resid) { 737144450Sjhb free(uio, M_IOV); 738144450Sjhb return (EINVAL); 739144450Sjhb } 740144450Sjhb uio->uio_resid += iov->iov_len; 741144450Sjhb iov++; 742144450Sjhb } 743144450Sjhb *uiop = uio; 744144450Sjhb return (0); 745144450Sjhb} 746100384Speter 747144450Sjhbint 748144450Sjhbfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) 749144450Sjhb{ 750144450Sjhb struct uio *auio; 751144450Sjhb int error; 752100384Speter 753144450Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 754144450Sjhb if (error) 755144450Sjhb return (error); 756144450Sjhb error = kern_readv(td, uap->fd, auio); 757144450Sjhb free(auio, M_IOV); 758100384Speter return (error); 759100384Speter} 760100384Speter 761100384Speterint 762119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) 763100384Speter{ 764144450Sjhb struct uio *auio; 765144450Sjhb int error; 766100384Speter 767144450Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 768144450Sjhb if (error) 769144450Sjhb return (error); 770144450Sjhb error = kern_writev(td, uap->fd, auio); 771144450Sjhb free(auio, M_IOV); 772100384Speter return (error); 773100384Speter} 774100384Speter 775100384Speterint 776147813Sjhbfreebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap) 777147813Sjhb{ 778147813Sjhb struct uio *auio; 779147813Sjhb int error; 780147813Sjhb 781147813Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 782147813Sjhb if (error) 783147813Sjhb return (error); 784147813Sjhb error = kern_preadv(td, uap->fd, auio, uap->offset); 785147813Sjhb free(auio, M_IOV); 786147813Sjhb return (error); 787147813Sjhb} 788147813Sjhb 789147813Sjhbint 790147813Sjhbfreebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap) 791147813Sjhb{ 792147813Sjhb struct uio *auio; 793147813Sjhb int error; 794147813Sjhb 795147813Sjhb error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); 796147813Sjhb if (error) 797147813Sjhb return (error); 798147813Sjhb error = kern_pwritev(td, uap->fd, auio, uap->offset); 799147813Sjhb free(auio, M_IOV); 800147813Sjhb return (error); 801147813Sjhb} 802147813Sjhb 803151359Spsstatic int 804151909Spsfreebsd32_copyiniov(struct iovec32 *iovp32, u_int iovcnt, struct iovec **iovp, 805151359Sps int error) 806151359Sps{ 807151359Sps struct iovec32 iov32; 808151909Sps struct iovec *iov; 809151909Sps u_int iovlen; 810151359Sps int i; 811151359Sps 812151909Sps *iovp = NULL; 813151359Sps if (iovcnt > UIO_MAXIOV) 814151359Sps return (error); 815151359Sps iovlen = iovcnt * sizeof(struct iovec); 816151909Sps iov = malloc(iovlen, M_IOV, M_WAITOK); 817151359Sps for (i = 0; i < iovcnt; i++) { 818151909Sps error = copyin(&iovp32[i], &iov32, sizeof(struct iovec32)); 819151359Sps if (error) { 820151909Sps free(iov, M_IOV); 821151359Sps return (error); 822151359Sps } 823151909Sps iov[i].iov_base = PTRIN(iov32.iov_base); 824151909Sps iov[i].iov_len = iov32.iov_len; 825151359Sps } 826151909Sps *iovp = iov; 827151359Sps return (0); 828151359Sps} 829151359Sps 830151909Spsstatic int 831151909Spsfreebsd32_copyoutiov(struct iovec *iov, u_int iovcnt, struct iovec32 *iovp, 832151909Sps int error) 833151909Sps{ 834151909Sps struct iovec32 iov32; 835151909Sps int i; 836151909Sps 837151909Sps if (iovcnt > UIO_MAXIOV) 838151909Sps return (error); 839151909Sps for (i = 0; i < iovcnt; i++) { 840151909Sps iov32.iov_base = PTROUT(iov[i].iov_base); 841151909Sps iov32.iov_len = iov[i].iov_len; 842151909Sps error = copyout(&iov32, &iovp[i], sizeof(iov32)); 843151909Sps if (error) 844151909Sps return (error); 845151909Sps } 846151909Sps return (0); 847151909Sps} 848151909Sps 849151909Sps 850151359Spsstruct msghdr32 { 851151359Sps u_int32_t msg_name; 852151359Sps socklen_t msg_namelen; 853151359Sps u_int32_t msg_iov; 854151359Sps int msg_iovlen; 855151359Sps u_int32_t msg_control; 856151359Sps socklen_t msg_controllen; 857151359Sps int msg_flags; 858151359Sps}; 859151359SpsCTASSERT(sizeof(struct msghdr32) == 28); 860151359Sps 861151359Spsstatic int 862151359Spsfreebsd32_copyinmsghdr(struct msghdr32 *msg32, struct msghdr *msg) 863151359Sps{ 864151359Sps struct msghdr32 m32; 865151359Sps int error; 866151359Sps 867151359Sps error = copyin(msg32, &m32, sizeof(m32)); 868151359Sps if (error) 869151359Sps return (error); 870151359Sps msg->msg_name = PTRIN(m32.msg_name); 871151359Sps msg->msg_namelen = m32.msg_namelen; 872151359Sps msg->msg_iov = PTRIN(m32.msg_iov); 873151359Sps msg->msg_iovlen = m32.msg_iovlen; 874151359Sps msg->msg_control = PTRIN(m32.msg_control); 875151359Sps msg->msg_controllen = m32.msg_controllen; 876151359Sps msg->msg_flags = m32.msg_flags; 877151909Sps return (0); 878151359Sps} 879151359Sps 880151359Spsstatic int 881151359Spsfreebsd32_copyoutmsghdr(struct msghdr *msg, struct msghdr32 *msg32) 882151359Sps{ 883151359Sps struct msghdr32 m32; 884151359Sps int error; 885151359Sps 886151359Sps m32.msg_name = PTROUT(msg->msg_name); 887151359Sps m32.msg_namelen = msg->msg_namelen; 888151359Sps m32.msg_iov = PTROUT(msg->msg_iov); 889151359Sps m32.msg_iovlen = msg->msg_iovlen; 890151359Sps m32.msg_control = PTROUT(msg->msg_control); 891151359Sps m32.msg_controllen = msg->msg_controllen; 892151359Sps m32.msg_flags = msg->msg_flags; 893151359Sps error = copyout(&m32, msg32, sizeof(m32)); 894151359Sps return (error); 895151359Sps} 896151359Sps 897151909Sps#define FREEBSD32_ALIGNBYTES (sizeof(int) - 1) 898151909Sps#define FREEBSD32_ALIGN(p) \ 899151909Sps (((u_long)(p) + FREEBSD32_ALIGNBYTES) & ~FREEBSD32_ALIGNBYTES) 900151909Sps#define FREEBSD32_CMSG_SPACE(l) \ 901151909Sps (FREEBSD32_ALIGN(sizeof(struct cmsghdr)) + FREEBSD32_ALIGN(l)) 902151909Sps 903151909Sps#define FREEBSD32_CMSG_DATA(cmsg) ((unsigned char *)(cmsg) + \ 904151909Sps FREEBSD32_ALIGN(sizeof(struct cmsghdr))) 905151909Spsstatic int 906151909Spsfreebsd32_copy_msg_out(struct msghdr *msg, struct mbuf *control) 907151909Sps{ 908151909Sps struct cmsghdr *cm; 909151909Sps void *data; 910151909Sps socklen_t clen, datalen; 911151909Sps int error; 912151909Sps caddr_t ctlbuf; 913151909Sps int len, maxlen, copylen; 914151909Sps struct mbuf *m; 915151909Sps error = 0; 916151909Sps 917151909Sps len = msg->msg_controllen; 918151909Sps maxlen = msg->msg_controllen; 919151909Sps msg->msg_controllen = 0; 920151909Sps 921151909Sps m = control; 922151909Sps ctlbuf = msg->msg_control; 923151909Sps 924151909Sps while (m && len > 0) { 925151909Sps cm = mtod(m, struct cmsghdr *); 926151909Sps clen = m->m_len; 927151909Sps 928151909Sps while (cm != NULL) { 929151909Sps 930151909Sps if (sizeof(struct cmsghdr) > clen || 931151909Sps cm->cmsg_len > clen) { 932151909Sps error = EINVAL; 933151909Sps break; 934151909Sps } 935151909Sps 936151909Sps data = CMSG_DATA(cm); 937151909Sps datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data; 938151909Sps 939151909Sps /* Adjust message length */ 940151909Sps cm->cmsg_len = FREEBSD32_ALIGN(sizeof(struct cmsghdr)) + 941151909Sps datalen; 942151909Sps 943151909Sps 944151909Sps /* Copy cmsghdr */ 945151909Sps copylen = sizeof(struct cmsghdr); 946151909Sps if (len < copylen) { 947151909Sps msg->msg_flags |= MSG_CTRUNC; 948151909Sps copylen = len; 949151909Sps } 950151909Sps 951151909Sps error = copyout(cm,ctlbuf,copylen); 952151909Sps if (error) 953151909Sps goto exit; 954151909Sps 955151909Sps ctlbuf += FREEBSD32_ALIGN(copylen); 956151909Sps len -= FREEBSD32_ALIGN(copylen); 957151909Sps 958151909Sps if (len <= 0) 959151909Sps break; 960151909Sps 961151909Sps /* Copy data */ 962151909Sps copylen = datalen; 963151909Sps if (len < copylen) { 964151909Sps msg->msg_flags |= MSG_CTRUNC; 965151909Sps copylen = len; 966151909Sps } 967151909Sps 968151909Sps error = copyout(data,ctlbuf,copylen); 969151909Sps if (error) 970151909Sps goto exit; 971151909Sps 972151909Sps ctlbuf += FREEBSD32_ALIGN(copylen); 973151909Sps len -= FREEBSD32_ALIGN(copylen); 974151909Sps 975151909Sps if (CMSG_SPACE(datalen) < clen) { 976151909Sps clen -= CMSG_SPACE(datalen); 977151909Sps cm = (struct cmsghdr *) 978151909Sps ((caddr_t)cm + CMSG_SPACE(datalen)); 979151909Sps } else { 980151909Sps clen = 0; 981151909Sps cm = NULL; 982151909Sps } 983151909Sps } 984151909Sps m = m->m_next; 985151909Sps } 986151909Sps 987151909Sps msg->msg_controllen = (len <= 0) ? maxlen : ctlbuf - (caddr_t)msg->msg_control; 988151909Sps 989151909Spsexit: 990151909Sps return (error); 991151909Sps 992151909Sps} 993151909Sps 994147813Sjhbint 995151359Spsfreebsd32_recvmsg(td, uap) 996151359Sps struct thread *td; 997151359Sps struct freebsd32_recvmsg_args /* { 998151359Sps int s; 999151359Sps struct msghdr32 *msg; 1000151359Sps int flags; 1001151359Sps } */ *uap; 1002151359Sps{ 1003151359Sps struct msghdr msg; 1004151359Sps struct msghdr32 m32; 1005151359Sps struct iovec *uiov, *iov; 1006151909Sps struct mbuf *control = NULL; 1007151909Sps struct mbuf **controlp; 1008151909Sps 1009151359Sps int error; 1010151359Sps error = copyin(uap->msg, &m32, sizeof(m32)); 1011151359Sps if (error) 1012151359Sps return (error); 1013151359Sps error = freebsd32_copyinmsghdr(uap->msg, &msg); 1014151359Sps if (error) 1015151359Sps return (error); 1016151359Sps error = freebsd32_copyiniov((struct iovec32 *)(uintptr_t)m32.msg_iov, 1017151359Sps m32.msg_iovlen, &iov, EMSGSIZE); 1018151359Sps if (error) 1019151359Sps return (error); 1020151359Sps msg.msg_flags = uap->flags; 1021151359Sps uiov = msg.msg_iov; 1022151359Sps msg.msg_iov = iov; 1023151909Sps 1024151909Sps controlp = (msg.msg_control != NULL) ? &control : NULL; 1025151909Sps error = kern_recvit(td, uap->s, &msg, NULL, UIO_USERSPACE, controlp); 1026151359Sps if (error == 0) { 1027151359Sps msg.msg_iov = uiov; 1028151909Sps 1029151909Sps if (control != NULL) 1030151909Sps error = freebsd32_copy_msg_out(&msg, control); 1031151909Sps 1032151909Sps if (error == 0) 1033151909Sps error = freebsd32_copyoutmsghdr(&msg, uap->msg); 1034151909Sps 1035151909Sps if (error == 0) 1036151909Sps error = freebsd32_copyoutiov(iov, iov->iov_len, 1037151909Sps (struct iovec32 *)(uintptr_t)m32.msg_iov, EMSGSIZE); 1038151359Sps } 1039151359Sps free(iov, M_IOV); 1040151909Sps 1041151909Sps if (control != NULL) 1042151909Sps m_freem(control); 1043151909Sps 1044151359Sps return (error); 1045151359Sps} 1046151359Sps 1047151909Sps 1048151909Spsstatic int 1049151909Spsfreebsd32_convert_msg_in(struct mbuf **controlp) 1050151909Sps{ 1051151909Sps struct mbuf *control = *controlp; 1052151909Sps struct cmsghdr *cm = mtod(control, struct cmsghdr *); 1053151909Sps void *data; 1054151909Sps socklen_t clen = control->m_len, datalen; 1055151909Sps int error; 1056151909Sps 1057151909Sps error = 0; 1058151909Sps *controlp = NULL; 1059151909Sps 1060151909Sps while (cm != NULL) { 1061151909Sps if (sizeof(struct cmsghdr) > clen || cm->cmsg_len > clen) { 1062151909Sps error = EINVAL; 1063151909Sps break; 1064151909Sps } 1065151909Sps 1066151909Sps data = FREEBSD32_CMSG_DATA(cm); 1067151909Sps datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data; 1068151909Sps 1069151909Sps *controlp = sbcreatecontrol(data, datalen, cm->cmsg_type, 1070151909Sps cm->cmsg_level); 1071151909Sps controlp = &(*controlp)->m_next; 1072151909Sps 1073151909Sps if (FREEBSD32_CMSG_SPACE(datalen) < clen) { 1074151909Sps clen -= FREEBSD32_CMSG_SPACE(datalen); 1075151909Sps cm = (struct cmsghdr *) 1076151909Sps ((caddr_t)cm + FREEBSD32_CMSG_SPACE(datalen)); 1077151909Sps } else { 1078151909Sps clen = 0; 1079151909Sps cm = NULL; 1080151909Sps } 1081151909Sps } 1082151909Sps 1083151909Sps m_freem(control); 1084151909Sps return (error); 1085151909Sps} 1086151909Sps 1087151909Sps 1088151359Spsint 1089151359Spsfreebsd32_sendmsg(struct thread *td, 1090151359Sps struct freebsd32_sendmsg_args *uap) 1091151359Sps{ 1092151359Sps struct msghdr msg; 1093151359Sps struct msghdr32 m32; 1094151359Sps struct iovec *iov; 1095151909Sps struct mbuf *control = NULL; 1096151909Sps struct sockaddr *to = NULL; 1097151359Sps int error; 1098151359Sps 1099151359Sps error = copyin(uap->msg, &m32, sizeof(m32)); 1100151359Sps if (error) 1101151359Sps return (error); 1102151359Sps error = freebsd32_copyinmsghdr(uap->msg, &msg); 1103151359Sps if (error) 1104151359Sps return (error); 1105151359Sps error = freebsd32_copyiniov((struct iovec32 *)(uintptr_t)m32.msg_iov, 1106151359Sps m32.msg_iovlen, &iov, EMSGSIZE); 1107151359Sps if (error) 1108151359Sps return (error); 1109151359Sps msg.msg_iov = iov; 1110151909Sps if (msg.msg_name != NULL) { 1111151909Sps error = getsockaddr(&to, msg.msg_name, msg.msg_namelen); 1112151909Sps if (error) { 1113151909Sps to = NULL; 1114151909Sps goto out; 1115151909Sps } 1116151909Sps msg.msg_name = to; 1117151909Sps } 1118151909Sps 1119151909Sps if (msg.msg_control) { 1120151909Sps if (msg.msg_controllen < sizeof(struct cmsghdr)) { 1121151909Sps error = EINVAL; 1122151909Sps goto out; 1123151909Sps } 1124151909Sps 1125151909Sps error = sockargs(&control, msg.msg_control, 1126151909Sps msg.msg_controllen, MT_CONTROL); 1127151909Sps if (error) 1128151909Sps goto out; 1129151909Sps 1130151909Sps error = freebsd32_convert_msg_in(&control); 1131151909Sps if (error) 1132151909Sps goto out; 1133151909Sps } 1134151909Sps 1135151909Sps error = kern_sendit(td, uap->s, &msg, uap->flags, control, 1136151909Sps UIO_USERSPACE); 1137151909Sps 1138151909Spsout: 1139151359Sps free(iov, M_IOV); 1140151909Sps if (to) 1141151909Sps free(to, M_SONAME); 1142151359Sps return (error); 1143151359Sps} 1144151359Sps 1145151359Spsint 1146151359Spsfreebsd32_recvfrom(struct thread *td, 1147151359Sps struct freebsd32_recvfrom_args *uap) 1148151359Sps{ 1149151359Sps struct msghdr msg; 1150151359Sps struct iovec aiov; 1151151359Sps int error; 1152151359Sps 1153151359Sps if (uap->fromlenaddr) { 1154151359Sps error = copyin((void *)(uintptr_t)uap->fromlenaddr, 1155151359Sps &msg.msg_namelen, sizeof(msg.msg_namelen)); 1156151359Sps if (error) 1157151359Sps return (error); 1158151359Sps } else { 1159151359Sps msg.msg_namelen = 0; 1160151359Sps } 1161151359Sps 1162151359Sps msg.msg_name = (void *)(uintptr_t)uap->from; 1163151359Sps msg.msg_iov = &aiov; 1164151359Sps msg.msg_iovlen = 1; 1165151359Sps aiov.iov_base = (void *)(uintptr_t)uap->buf; 1166151359Sps aiov.iov_len = uap->len; 1167151359Sps msg.msg_control = 0; 1168151359Sps msg.msg_flags = uap->flags; 1169151909Sps error = kern_recvit(td, uap->s, &msg, 1170151909Sps (void *)(uintptr_t)uap->fromlenaddr, UIO_USERSPACE, NULL); 1171151359Sps return (error); 1172151359Sps} 1173151359Sps 1174151359Spsint 1175119333Speterfreebsd32_settimeofday(struct thread *td, 1176119333Speter struct freebsd32_settimeofday_args *uap) 1177100384Speter{ 1178144450Sjhb struct timeval32 tv32; 1179144450Sjhb struct timeval tv, *tvp; 1180144450Sjhb struct timezone tz, *tzp; 1181100384Speter int error; 1182100384Speter 1183144450Sjhb if (uap->tv) { 1184144450Sjhb error = copyin(uap->tv, &tv32, sizeof(tv32)); 1185100384Speter if (error) 1186100384Speter return (error); 1187144450Sjhb CP(tv32, tv, tv_sec); 1188144450Sjhb CP(tv32, tv, tv_usec); 1189144450Sjhb tvp = &tv; 1190144450Sjhb } else 1191144450Sjhb tvp = NULL; 1192144450Sjhb if (uap->tzp) { 1193144450Sjhb error = copyin(uap->tzp, &tz, sizeof(tz)); 1194100384Speter if (error) 1195100384Speter return (error); 1196144450Sjhb tzp = &tz; 1197144450Sjhb } else 1198144450Sjhb tzp = NULL; 1199144450Sjhb return (kern_settimeofday(td, tvp, tzp)); 1200100384Speter} 1201100384Speter 1202100384Speterint 1203119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap) 1204100384Speter{ 1205142059Sjhb struct timeval32 s32[2]; 1206142059Sjhb struct timeval s[2], *sp; 1207100384Speter int error; 1208100384Speter 1209142059Sjhb if (uap->tptr != NULL) { 1210142059Sjhb error = copyin(uap->tptr, s32, sizeof(s32)); 1211100384Speter if (error) 1212100384Speter return (error); 1213100384Speter CP(s32[0], s[0], tv_sec); 1214100384Speter CP(s32[0], s[0], tv_usec); 1215100384Speter CP(s32[1], s[1], tv_sec); 1216100384Speter CP(s32[1], s[1], tv_usec); 1217142059Sjhb sp = s; 1218142059Sjhb } else 1219142059Sjhb sp = NULL; 1220142059Sjhb return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE)); 1221100384Speter} 1222100384Speter 1223100384Speterint 1224119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) 1225100384Speter{ 1226144450Sjhb struct timeval32 tv32; 1227144450Sjhb struct timeval delta, olddelta, *deltap; 1228100384Speter int error; 1229100384Speter 1230144450Sjhb if (uap->delta) { 1231144450Sjhb error = copyin(uap->delta, &tv32, sizeof(tv32)); 1232100384Speter if (error) 1233100384Speter return (error); 1234144450Sjhb CP(tv32, delta, tv_sec); 1235144450Sjhb CP(tv32, delta, tv_usec); 1236144450Sjhb deltap = δ 1237144450Sjhb } else 1238144450Sjhb deltap = NULL; 1239144450Sjhb error = kern_adjtime(td, deltap, &olddelta); 1240144450Sjhb if (uap->olddelta && error == 0) { 1241144450Sjhb CP(olddelta, tv32, tv_sec); 1242144450Sjhb CP(olddelta, tv32, tv_usec); 1243144450Sjhb error = copyout(&tv32, uap->olddelta, sizeof(tv32)); 1244100384Speter } 1245100384Speter return (error); 1246100384Speter} 1247100384Speter 1248128597Smarcel#ifdef COMPAT_FREEBSD4 1249100384Speterint 1250128260Speterfreebsd4_freebsd32_statfs(struct thread *td, struct freebsd4_freebsd32_statfs_args *uap) 1251100384Speter{ 1252142059Sjhb struct statfs32 s32; 1253142059Sjhb struct statfs s; 1254100384Speter int error; 1255100384Speter 1256142059Sjhb error = kern_statfs(td, uap->path, UIO_USERSPACE, &s); 1257100384Speter if (error) 1258100384Speter return (error); 1259142059Sjhb copy_statfs(&s, &s32); 1260142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 1261100384Speter} 1262128597Smarcel#endif 1263100384Speter 1264128597Smarcel#ifdef COMPAT_FREEBSD4 1265100384Speterint 1266128260Speterfreebsd4_freebsd32_fstatfs(struct thread *td, struct freebsd4_freebsd32_fstatfs_args *uap) 1267100384Speter{ 1268142059Sjhb struct statfs32 s32; 1269142059Sjhb struct statfs s; 1270100384Speter int error; 1271100384Speter 1272142059Sjhb error = kern_fstatfs(td, uap->fd, &s); 1273100384Speter if (error) 1274100384Speter return (error); 1275142059Sjhb copy_statfs(&s, &s32); 1276142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 1277100384Speter} 1278128597Smarcel#endif 1279100384Speter 1280128597Smarcel#ifdef COMPAT_FREEBSD4 1281100384Speterint 1282128260Speterfreebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatfs_args *uap) 1283128260Speter{ 1284142059Sjhb struct statfs32 s32; 1285142059Sjhb struct statfs s; 1286142059Sjhb fhandle_t fh; 1287128260Speter int error; 1288128260Speter 1289142059Sjhb if ((error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t))) != 0) 1290142059Sjhb return (error); 1291142059Sjhb error = kern_fhstatfs(td, fh, &s); 1292128260Speter if (error) 1293128260Speter return (error); 1294142059Sjhb copy_statfs(&s, &s32); 1295142059Sjhb return (copyout(&s32, uap->buf, sizeof(s32))); 1296128260Speter} 1297128597Smarcel#endif 1298128260Speter 1299128260Speterint 1300119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap) 1301100384Speter{ 1302100384Speter /* 1303100384Speter * Vector through to semsys if it is loaded. 1304100384Speter */ 1305150883Sjhb return sysent[SYS_semsys].sy_call(td, uap); 1306100384Speter} 1307100384Speter 1308100384Speterint 1309119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap) 1310100384Speter{ 1311100384Speter /* 1312100384Speter * Vector through to msgsys if it is loaded. 1313100384Speter */ 1314150883Sjhb return sysent[SYS_msgsys].sy_call(td, uap); 1315100384Speter} 1316100384Speter 1317100384Speterint 1318119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap) 1319100384Speter{ 1320100384Speter /* 1321100384Speter * Vector through to shmsys if it is loaded. 1322100384Speter */ 1323150883Sjhb return sysent[SYS_shmsys].sy_call(td, uap); 1324100384Speter} 1325100384Speter 1326100384Speterint 1327119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) 1328100384Speter{ 1329100384Speter struct pread_args ap; 1330100384Speter 1331107849Salfred ap.fd = uap->fd; 1332107849Salfred ap.buf = uap->buf; 1333107849Salfred ap.nbyte = uap->nbyte; 1334119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1335100384Speter return (pread(td, &ap)); 1336100384Speter} 1337100384Speter 1338100384Speterint 1339119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap) 1340100384Speter{ 1341100384Speter struct pwrite_args ap; 1342100384Speter 1343107849Salfred ap.fd = uap->fd; 1344107849Salfred ap.buf = uap->buf; 1345107849Salfred ap.nbyte = uap->nbyte; 1346119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1347100384Speter return (pwrite(td, &ap)); 1348100384Speter} 1349100384Speter 1350100384Speterint 1351119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap) 1352100384Speter{ 1353100384Speter int error; 1354100384Speter struct lseek_args ap; 1355100384Speter off_t pos; 1356100384Speter 1357107849Salfred ap.fd = uap->fd; 1358119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1359107849Salfred ap.whence = uap->whence; 1360100384Speter error = lseek(td, &ap); 1361100384Speter /* Expand the quad return into two parts for eax and edx */ 1362100384Speter pos = *(off_t *)(td->td_retval); 1363100384Speter td->td_retval[0] = pos & 0xffffffff; /* %eax */ 1364100384Speter td->td_retval[1] = pos >> 32; /* %edx */ 1365100384Speter return error; 1366100384Speter} 1367100384Speter 1368100384Speterint 1369119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap) 1370100384Speter{ 1371100384Speter struct truncate_args ap; 1372100384Speter 1373107849Salfred ap.path = uap->path; 1374119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1375100384Speter return (truncate(td, &ap)); 1376100384Speter} 1377100384Speter 1378100384Speterint 1379119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) 1380100384Speter{ 1381100384Speter struct ftruncate_args ap; 1382100384Speter 1383107849Salfred ap.fd = uap->fd; 1384119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1385100384Speter return (ftruncate(td, &ap)); 1386100384Speter} 1387100384Speter 1388104738Speter#ifdef COMPAT_FREEBSD4 1389100384Speterint 1390119333Speterfreebsd4_freebsd32_sendfile(struct thread *td, 1391119333Speter struct freebsd4_freebsd32_sendfile_args *uap) 1392104738Speter{ 1393104738Speter struct freebsd4_sendfile_args ap; 1394104738Speter 1395107849Salfred ap.fd = uap->fd; 1396107849Salfred ap.s = uap->s; 1397119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1398107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1399107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1400107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1401107849Salfred ap.flags = uap->flags; 1402104738Speter return (freebsd4_sendfile(td, &ap)); 1403104738Speter} 1404104738Speter#endif 1405104738Speter 1406104738Speterint 1407119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap) 1408100384Speter{ 1409100384Speter struct sendfile_args ap; 1410100384Speter 1411107849Salfred ap.fd = uap->fd; 1412107849Salfred ap.s = uap->s; 1413119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1414107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1415107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1416107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1417107849Salfred ap.flags = uap->flags; 1418100384Speter return (sendfile(td, &ap)); 1419100384Speter} 1420100384Speter 1421100384Speterstruct stat32 { 1422130640Sphk dev_t st_dev; 1423100384Speter ino_t st_ino; 1424100384Speter mode_t st_mode; 1425100384Speter nlink_t st_nlink; 1426100384Speter uid_t st_uid; 1427100384Speter gid_t st_gid; 1428130640Sphk dev_t st_rdev; 1429100384Speter struct timespec32 st_atimespec; 1430100384Speter struct timespec32 st_mtimespec; 1431100384Speter struct timespec32 st_ctimespec; 1432100384Speter off_t st_size; 1433100384Speter int64_t st_blocks; 1434100384Speter u_int32_t st_blksize; 1435100384Speter u_int32_t st_flags; 1436100384Speter u_int32_t st_gen; 1437121719Speter struct timespec32 st_birthtimespec; 1438121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1439121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1440100384Speter}; 1441100384Speter 1442121719Speter 1443121719SpeterCTASSERT(sizeof(struct stat32) == 96); 1444121719Speter 1445100384Speterstatic void 1446100384Spetercopy_stat( struct stat *in, struct stat32 *out) 1447100384Speter{ 1448100384Speter CP(*in, *out, st_dev); 1449100384Speter CP(*in, *out, st_ino); 1450100384Speter CP(*in, *out, st_mode); 1451100384Speter CP(*in, *out, st_nlink); 1452100384Speter CP(*in, *out, st_uid); 1453100384Speter CP(*in, *out, st_gid); 1454100384Speter CP(*in, *out, st_rdev); 1455100384Speter TS_CP(*in, *out, st_atimespec); 1456100384Speter TS_CP(*in, *out, st_mtimespec); 1457100384Speter TS_CP(*in, *out, st_ctimespec); 1458100384Speter CP(*in, *out, st_size); 1459100384Speter CP(*in, *out, st_blocks); 1460100384Speter CP(*in, *out, st_blksize); 1461100384Speter CP(*in, *out, st_flags); 1462100384Speter CP(*in, *out, st_gen); 1463100384Speter} 1464100384Speter 1465100384Speterint 1466119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap) 1467100384Speter{ 1468123746Speter struct stat sb; 1469123746Speter struct stat32 sb32; 1470100384Speter int error; 1471100384Speter 1472142059Sjhb error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); 1473100384Speter if (error) 1474100384Speter return (error); 1475123746Speter copy_stat(&sb, &sb32); 1476123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1477100384Speter return (error); 1478100384Speter} 1479100384Speter 1480100384Speterint 1481119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap) 1482100384Speter{ 1483123746Speter struct stat ub; 1484123746Speter struct stat32 ub32; 1485100384Speter int error; 1486100384Speter 1487142059Sjhb error = kern_fstat(td, uap->fd, &ub); 1488100384Speter if (error) 1489100384Speter return (error); 1490123746Speter copy_stat(&ub, &ub32); 1491123746Speter error = copyout(&ub32, uap->ub, sizeof(ub32)); 1492100384Speter return (error); 1493100384Speter} 1494100384Speter 1495100384Speterint 1496119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap) 1497100384Speter{ 1498123746Speter struct stat sb; 1499123746Speter struct stat32 sb32; 1500142059Sjhb int error; 1501100384Speter 1502142059Sjhb error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); 1503100384Speter if (error) 1504100384Speter return (error); 1505123746Speter copy_stat(&sb, &sb32); 1506123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1507100384Speter return (error); 1508100384Speter} 1509100384Speter 1510100384Speter/* 1511100384Speter * MPSAFE 1512100384Speter */ 1513100384Speterint 1514119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap) 1515100384Speter{ 1516100384Speter int error, name[CTL_MAXNAME]; 1517100384Speter size_t j, oldlen; 1518100384Speter 1519100384Speter if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1520100384Speter return (EINVAL); 1521136404Speter error = copyin(uap->name, name, uap->namelen * sizeof(int)); 1522100384Speter if (error) 1523100384Speter return (error); 1524100384Speter mtx_lock(&Giant); 1525100384Speter if (uap->oldlenp) 1526100384Speter oldlen = fuword32(uap->oldlenp); 1527100384Speter else 1528100384Speter oldlen = 0; 1529100384Speter error = userland_sysctl(td, name, uap->namelen, 1530100384Speter uap->old, &oldlen, 1, 1531136404Speter uap->new, uap->newlen, &j, SCTL_MASK32); 1532100384Speter if (error && error != ENOMEM) 1533100384Speter goto done2; 1534136404Speter if (uap->oldlenp) 1535100384Speter suword32(uap->oldlenp, j); 1536100384Speterdone2: 1537100384Speter mtx_unlock(&Giant); 1538100384Speter return (error); 1539100384Speter} 1540100384Speter 1541100384Speterstruct sigaction32 { 1542100384Speter u_int32_t sa_u; 1543100384Speter int sa_flags; 1544100384Speter sigset_t sa_mask; 1545100384Speter}; 1546100384Speter 1547121719SpeterCTASSERT(sizeof(struct sigaction32) == 24); 1548121719Speter 1549100384Speterint 1550119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap) 1551100384Speter{ 1552113859Sjhb struct sigaction32 s32; 1553113859Sjhb struct sigaction sa, osa, *sap; 1554100384Speter int error; 1555100384Speter 1556113859Sjhb if (uap->act) { 1557113859Sjhb error = copyin(uap->act, &s32, sizeof(s32)); 1558100384Speter if (error) 1559100384Speter return (error); 1560113859Sjhb sa.sa_handler = PTRIN(s32.sa_u); 1561113859Sjhb CP(s32, sa, sa_flags); 1562113859Sjhb CP(s32, sa, sa_mask); 1563113859Sjhb sap = &sa; 1564113859Sjhb } else 1565113859Sjhb sap = NULL; 1566113859Sjhb error = kern_sigaction(td, uap->sig, sap, &osa, 0); 1567146583Sps if (error == 0 && uap->oact != NULL) { 1568113859Sjhb s32.sa_u = PTROUT(osa.sa_handler); 1569113859Sjhb CP(osa, s32, sa_flags); 1570113859Sjhb CP(osa, s32, sa_mask); 1571113859Sjhb error = copyout(&s32, uap->oact, sizeof(s32)); 1572100384Speter } 1573100384Speter return (error); 1574100384Speter} 1575100384Speter 1576114987Speter#ifdef COMPAT_FREEBSD4 1577114987Speterint 1578119333Speterfreebsd4_freebsd32_sigaction(struct thread *td, 1579119333Speter struct freebsd4_freebsd32_sigaction_args *uap) 1580114987Speter{ 1581114987Speter struct sigaction32 s32; 1582114987Speter struct sigaction sa, osa, *sap; 1583114987Speter int error; 1584114987Speter 1585114987Speter if (uap->act) { 1586114987Speter error = copyin(uap->act, &s32, sizeof(s32)); 1587114987Speter if (error) 1588114987Speter return (error); 1589114987Speter sa.sa_handler = PTRIN(s32.sa_u); 1590114987Speter CP(s32, sa, sa_flags); 1591114987Speter CP(s32, sa, sa_mask); 1592114987Speter sap = &sa; 1593114987Speter } else 1594114987Speter sap = NULL; 1595114987Speter error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4); 1596146583Sps if (error == 0 && uap->oact != NULL) { 1597114987Speter s32.sa_u = PTROUT(osa.sa_handler); 1598114987Speter CP(osa, s32, sa_flags); 1599114987Speter CP(osa, s32, sa_mask); 1600114987Speter error = copyout(&s32, uap->oact, sizeof(s32)); 1601114987Speter } 1602114987Speter return (error); 1603114987Speter} 1604114987Speter#endif 1605114987Speter 1606151582Sps#ifdef COMPAT_43 1607151720Speterstruct osigaction32 { 1608151582Sps u_int32_t sa_u; 1609151582Sps osigset_t sa_mask; 1610151582Sps int sa_flags; 1611151582Sps}; 1612151582Sps 1613151582Sps#define ONSIG 32 1614151582Sps 1615140481Spsint 1616151720Speterofreebsd32_sigaction(struct thread *td, 1617151720Speter struct ofreebsd32_sigaction_args *uap) 1618151582Sps{ 1619151720Speter struct osigaction32 s32; 1620151582Sps struct sigaction sa, osa, *sap; 1621151582Sps int error; 1622151582Sps 1623151582Sps if (uap->signum <= 0 || uap->signum >= ONSIG) 1624151582Sps return (EINVAL); 1625151582Sps 1626151582Sps if (uap->nsa) { 1627151582Sps error = copyin(uap->nsa, &s32, sizeof(s32)); 1628151582Sps if (error) 1629151582Sps return (error); 1630151582Sps sa.sa_handler = PTRIN(s32.sa_u); 1631151582Sps CP(s32, sa, sa_flags); 1632151582Sps OSIG2SIG(s32.sa_mask, sa.sa_mask); 1633151582Sps sap = &sa; 1634151582Sps } else 1635151582Sps sap = NULL; 1636151582Sps error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET); 1637151582Sps if (error == 0 && uap->osa != NULL) { 1638151582Sps s32.sa_u = PTROUT(osa.sa_handler); 1639151582Sps CP(osa, s32, sa_flags); 1640151582Sps SIG2OSIG(osa.sa_mask, s32.sa_mask); 1641151582Sps error = copyout(&s32, uap->osa, sizeof(s32)); 1642151582Sps } 1643151582Sps return (error); 1644151582Sps} 1645151582Sps 1646151582Spsint 1647151720Speterofreebsd32_sigprocmask(struct thread *td, 1648151720Speter struct ofreebsd32_sigprocmask_args *uap) 1649151582Sps{ 1650151582Sps sigset_t set, oset; 1651151582Sps int error; 1652151582Sps 1653151582Sps OSIG2SIG(uap->mask, set); 1654151582Sps error = kern_sigprocmask(td, uap->how, &set, &oset, 1); 1655151582Sps SIG2OSIG(oset, td->td_retval[0]); 1656151582Sps return (error); 1657151582Sps} 1658151582Sps 1659151582Spsint 1660151720Speterofreebsd32_sigpending(struct thread *td, 1661151720Speter struct ofreebsd32_sigpending_args *uap) 1662151582Sps{ 1663151582Sps struct proc *p = td->td_proc; 1664151582Sps sigset_t siglist; 1665151582Sps 1666151582Sps PROC_LOCK(p); 1667151582Sps siglist = p->p_siglist; 1668151582Sps SIGSETOR(siglist, td->td_siglist); 1669151582Sps PROC_UNLOCK(p); 1670151582Sps SIG2OSIG(siglist, td->td_retval[0]); 1671151582Sps return (0); 1672151582Sps} 1673151582Sps 1674151582Spsstruct sigvec32 { 1675151582Sps u_int32_t sv_handler; 1676151582Sps int sv_mask; 1677151582Sps int sv_flags; 1678151582Sps}; 1679151582Sps 1680151582Spsint 1681151720Speterofreebsd32_sigvec(struct thread *td, 1682151720Speter struct ofreebsd32_sigvec_args *uap) 1683151582Sps{ 1684151582Sps struct sigvec32 vec; 1685151582Sps struct sigaction sa, osa, *sap; 1686151582Sps int error; 1687151582Sps 1688151582Sps if (uap->signum <= 0 || uap->signum >= ONSIG) 1689151582Sps return (EINVAL); 1690151582Sps 1691151582Sps if (uap->nsv) { 1692151582Sps error = copyin(uap->nsv, &vec, sizeof(vec)); 1693151582Sps if (error) 1694151582Sps return (error); 1695151582Sps sa.sa_handler = PTRIN(vec.sv_handler); 1696151582Sps OSIG2SIG(vec.sv_mask, sa.sa_mask); 1697151582Sps sa.sa_flags = vec.sv_flags; 1698151582Sps sa.sa_flags ^= SA_RESTART; 1699151582Sps sap = &sa; 1700151582Sps } else 1701151582Sps sap = NULL; 1702151582Sps error = kern_sigaction(td, uap->signum, sap, &osa, KSA_OSIGSET); 1703151582Sps if (error == 0 && uap->osv != NULL) { 1704151582Sps vec.sv_handler = PTROUT(osa.sa_handler); 1705151582Sps SIG2OSIG(osa.sa_mask, vec.sv_mask); 1706151582Sps vec.sv_flags = osa.sa_flags; 1707151582Sps vec.sv_flags &= ~SA_NOCLDWAIT; 1708151582Sps vec.sv_flags ^= SA_RESTART; 1709151582Sps error = copyout(&vec, uap->osv, sizeof(vec)); 1710151582Sps } 1711151582Sps return (error); 1712151582Sps} 1713151582Sps 1714151582Spsint 1715151720Speterofreebsd32_sigblock(struct thread *td, 1716151720Speter struct ofreebsd32_sigblock_args *uap) 1717151582Sps{ 1718151582Sps struct proc *p = td->td_proc; 1719151582Sps sigset_t set; 1720151582Sps 1721151582Sps OSIG2SIG(uap->mask, set); 1722151582Sps SIG_CANTMASK(set); 1723151582Sps PROC_LOCK(p); 1724151582Sps SIG2OSIG(td->td_sigmask, td->td_retval[0]); 1725151582Sps SIGSETOR(td->td_sigmask, set); 1726151582Sps PROC_UNLOCK(p); 1727151582Sps return (0); 1728151582Sps} 1729151582Sps 1730151582Spsint 1731151720Speterofreebsd32_sigsetmask(struct thread *td, 1732151720Speter struct ofreebsd32_sigsetmask_args *uap) 1733151582Sps{ 1734151582Sps struct proc *p = td->td_proc; 1735151582Sps sigset_t set; 1736151582Sps 1737151582Sps OSIG2SIG(uap->mask, set); 1738151582Sps SIG_CANTMASK(set); 1739151582Sps PROC_LOCK(p); 1740151582Sps SIG2OSIG(td->td_sigmask, td->td_retval[0]); 1741151582Sps SIGSETLO(td->td_sigmask, set); 1742151582Sps signotify(td); 1743151582Sps PROC_UNLOCK(p); 1744151582Sps return (0); 1745151582Sps} 1746151582Sps 1747151582Spsint 1748151720Speterofreebsd32_sigsuspend(struct thread *td, 1749151720Speter struct ofreebsd32_sigsuspend_args *uap) 1750151582Sps{ 1751151582Sps struct proc *p = td->td_proc; 1752151582Sps sigset_t mask; 1753151582Sps 1754151582Sps PROC_LOCK(p); 1755151582Sps td->td_oldsigmask = td->td_sigmask; 1756151582Sps td->td_pflags |= TDP_OLDMASK; 1757151582Sps OSIG2SIG(uap->mask, mask); 1758151582Sps SIG_CANTMASK(mask); 1759151582Sps SIGSETLO(td->td_sigmask, mask); 1760151582Sps signotify(td); 1761151582Sps while (msleep(&p->p_sigacts, &p->p_mtx, PPAUSE|PCATCH, "opause", 0) == 0) 1762151582Sps /* void */; 1763151582Sps PROC_UNLOCK(p); 1764151582Sps /* always return EINTR rather than ERESTART... */ 1765151582Sps return (EINTR); 1766151582Sps} 1767151582Sps 1768151582Spsstruct sigstack32 { 1769151582Sps u_int32_t ss_sp; 1770151582Sps int ss_onstack; 1771151582Sps}; 1772151582Sps 1773151582Spsint 1774151720Speterofreebsd32_sigstack(struct thread *td, 1775151720Speter struct ofreebsd32_sigstack_args *uap) 1776151582Sps{ 1777151582Sps struct sigstack32 s32; 1778151582Sps struct sigstack nss, oss; 1779151582Sps int error = 0; 1780151582Sps 1781151582Sps if (uap->nss != NULL) { 1782151582Sps error = copyin(uap->nss, &s32, sizeof(s32)); 1783151582Sps if (error) 1784151582Sps return (error); 1785151582Sps nss.ss_sp = PTRIN(s32.ss_sp); 1786151582Sps CP(s32, nss, ss_onstack); 1787151582Sps } 1788151582Sps oss.ss_sp = td->td_sigstk.ss_sp; 1789151582Sps oss.ss_onstack = sigonstack(cpu_getstack(td)); 1790151582Sps if (uap->nss != NULL) { 1791151582Sps td->td_sigstk.ss_sp = nss.ss_sp; 1792151582Sps td->td_sigstk.ss_size = 0; 1793151582Sps td->td_sigstk.ss_flags |= nss.ss_onstack & SS_ONSTACK; 1794151582Sps td->td_pflags |= TDP_ALTSTACK; 1795151582Sps } 1796151582Sps if (uap->oss != NULL) { 1797151582Sps s32.ss_sp = PTROUT(oss.ss_sp); 1798151582Sps CP(oss, s32, ss_onstack); 1799151582Sps error = copyout(&s32, uap->oss, sizeof(s32)); 1800151582Sps } 1801151582Sps return (error); 1802151582Sps} 1803151582Sps#endif 1804151582Sps 1805151582Spsint 1806140481Spsfreebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap) 1807140481Sps{ 1808140481Sps struct timespec32 rmt32, rqt32; 1809140481Sps struct timespec rmt, rqt; 1810140481Sps int error; 1811140481Sps 1812151355Sps error = copyin(uap->rqtp, &rqt32, sizeof(rqt32)); 1813140481Sps if (error) 1814140481Sps return (error); 1815140481Sps 1816140481Sps CP(rqt32, rqt, tv_sec); 1817140481Sps CP(rqt32, rqt, tv_nsec); 1818140481Sps 1819140481Sps if (uap->rmtp && 1820140481Sps !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE)) 1821140481Sps return (EFAULT); 1822140481Sps error = kern_nanosleep(td, &rqt, &rmt); 1823140481Sps if (error && uap->rmtp) { 1824140481Sps int error2; 1825140481Sps 1826140481Sps CP(rmt, rmt32, tv_sec); 1827140481Sps CP(rmt, rmt32, tv_nsec); 1828140481Sps 1829151355Sps error2 = copyout(&rmt32, uap->rmtp, sizeof(rmt32)); 1830140481Sps if (error2) 1831140481Sps error = error2; 1832140481Sps } 1833140481Sps return (error); 1834140481Sps} 1835140481Sps 1836151357Spsint 1837151357Spsfreebsd32_clock_gettime(struct thread *td, 1838151357Sps struct freebsd32_clock_gettime_args *uap) 1839151357Sps{ 1840151357Sps struct timespec ats; 1841151357Sps struct timespec32 ats32; 1842151357Sps int error; 1843151357Sps 1844151357Sps error = kern_clock_gettime(td, uap->clock_id, &ats); 1845151357Sps if (error == 0) { 1846151357Sps CP(ats, ats32, tv_sec); 1847151357Sps CP(ats, ats32, tv_nsec); 1848151357Sps error = copyout(&ats32, uap->tp, sizeof(ats32)); 1849151357Sps } 1850151357Sps return (error); 1851151357Sps} 1852151357Sps 1853151357Spsint 1854151357Spsfreebsd32_clock_settime(struct thread *td, 1855151357Sps struct freebsd32_clock_settime_args *uap) 1856151357Sps{ 1857151357Sps struct timespec ats; 1858151357Sps struct timespec32 ats32; 1859151357Sps int error; 1860151357Sps 1861151357Sps error = copyin(uap->tp, &ats32, sizeof(ats32)); 1862151357Sps if (error) 1863151357Sps return (error); 1864151357Sps CP(ats32, ats, tv_sec); 1865151357Sps CP(ats32, ats, tv_nsec); 1866151357Sps 1867151357Sps return (kern_clock_settime(td, uap->clock_id, &ats)); 1868151357Sps} 1869151357Sps 1870151357Spsint 1871151357Spsfreebsd32_clock_getres(struct thread *td, 1872151357Sps struct freebsd32_clock_getres_args *uap) 1873151357Sps{ 1874151357Sps struct timespec ts; 1875151357Sps struct timespec32 ts32; 1876151357Sps int error; 1877151357Sps 1878151357Sps if (uap->tp == NULL) 1879151357Sps return (0); 1880151357Sps error = kern_clock_getres(td, uap->clock_id, &ts); 1881151357Sps if (error == 0) { 1882151357Sps CP(ts, ts32, tv_sec); 1883151357Sps CP(ts, ts32, tv_nsec); 1884151357Sps error = copyout(&ts32, uap->tp, sizeof(ts32)); 1885151357Sps } 1886151357Sps return (error); 1887151357Sps} 1888151357Sps 1889100384Speter#if 0 1890100384Speter 1891100384Speterint 1892119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) 1893100384Speter{ 1894100384Speter int error; 1895100384Speter struct yyy32 *p32, s32; 1896100384Speter struct yyy *p = NULL, s; 1897100384Speter 1898147654Sjhb if (uap->zzz) { 1899147654Sjhb error = copyin(uap->zzz, &s32, sizeof(s32)); 1900100384Speter if (error) 1901100384Speter return (error); 1902100384Speter /* translate in */ 1903147654Sjhb p = &s; 1904100384Speter } 1905147654Sjhb error = kern_xxx(td, p); 1906100384Speter if (error) 1907100384Speter return (error); 1908147654Sjhb if (uap->zzz) { 1909100384Speter /* translate out */ 1910100384Speter error = copyout(&s32, p32, sizeof(s32)); 1911100384Speter } 1912100384Speter return (error); 1913100384Speter} 1914100384Speter 1915100384Speter#endif 1916