freebsd32_misc.c revision 127140
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 127140 2004-03-17 20:00:00Z jhb $"); 29118031Sobrien 30104738Speter#include "opt_compat.h" 31104738Speter 32100384Speter#include <sys/param.h> 33100384Speter#include <sys/systm.h> 34100384Speter#include <sys/bus.h> 35100384Speter#include <sys/exec.h> 36100384Speter#include <sys/fcntl.h> 37100384Speter#include <sys/filedesc.h> 38123746Speter#include <sys/namei.h> 39100384Speter#include <sys/imgact.h> 40100384Speter#include <sys/kernel.h> 41100384Speter#include <sys/lock.h> 42100384Speter#include <sys/malloc.h> 43100384Speter#include <sys/file.h> /* Must come after sys/malloc.h */ 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> 55100384Speter#include <sys/pipe.h> /* Must come after sys/selinfo.h */ 56100384Speter#include <sys/signal.h> 57100384Speter#include <sys/signalvar.h> 58100384Speter#include <sys/socket.h> 59100384Speter#include <sys/socketvar.h> 60100384Speter#include <sys/stat.h> 61113859Sjhb#include <sys/syscallsubr.h> 62100384Speter#include <sys/sysctl.h> 63100384Speter#include <sys/sysent.h> 64100384Speter#include <sys/sysproto.h> 65100384Speter#include <sys/systm.h> 66100384Speter#include <sys/unistd.h> 67100384Speter#include <sys/user.h> 68100384Speter#include <sys/utsname.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 80119333Speter#include <compat/freebsd32/freebsd32_util.h> 81119333Speter#include <compat/freebsd32/freebsd32.h> 82119333Speter#include <compat/freebsd32/freebsd32_proto.h> 83100384Speter 84121719SpeterCTASSERT(sizeof(struct timeval32) == 8); 85121719SpeterCTASSERT(sizeof(struct timespec32) == 8); 86121719SpeterCTASSERT(sizeof(struct statfs32) == 256); 87121719SpeterCTASSERT(sizeof(struct rusage32) == 72); 88121719Speter 89100384Speterint 90119333Speterfreebsd32_wait4(struct thread *td, struct freebsd32_wait4_args *uap) 91100384Speter{ 92127140Sjhb int error, status; 93127140Sjhb struct rusage32 ru32; 94127140Sjhb struct rusage ru; 95100384Speter 96127140Sjhb error = kern_wait(td, uap->pid, &status, uap->options, &ru); 97100384Speter if (error) 98100384Speter return (error); 99127140Sjhb if (uap->status != NULL) 100127140Sjhb error = copyout(&status, uap->status, sizeof(status)); 101127140Sjhb if (uap->rusage != NULL && error == 0) { 102100384Speter TV_CP(ru, ru32, ru_utime); 103100384Speter TV_CP(ru, ru32, ru_stime); 104100384Speter CP(ru, ru32, ru_maxrss); 105100384Speter CP(ru, ru32, ru_ixrss); 106100384Speter CP(ru, ru32, ru_idrss); 107100384Speter CP(ru, ru32, ru_isrss); 108100384Speter CP(ru, ru32, ru_minflt); 109100384Speter CP(ru, ru32, ru_majflt); 110100384Speter CP(ru, ru32, ru_nswap); 111100384Speter CP(ru, ru32, ru_inblock); 112100384Speter CP(ru, ru32, ru_oublock); 113100384Speter CP(ru, ru32, ru_msgsnd); 114100384Speter CP(ru, ru32, ru_msgrcv); 115100384Speter CP(ru, ru32, ru_nsignals); 116100384Speter CP(ru, ru32, ru_nvcsw); 117100384Speter CP(ru, ru32, ru_nivcsw); 118127140Sjhb error = copyout(&ru32, uap->rusage, sizeof(ru32)); 119100384Speter } 120100384Speter return (error); 121100384Speter} 122100384Speter 123100384Speterstatic void 124100384Spetercopy_statfs(struct statfs *in, struct statfs32 *out) 125100384Speter{ 126100384Speter CP(*in, *out, f_bsize); 127100384Speter CP(*in, *out, f_iosize); 128100384Speter CP(*in, *out, f_blocks); 129100384Speter CP(*in, *out, f_bfree); 130100384Speter CP(*in, *out, f_bavail); 131100384Speter CP(*in, *out, f_files); 132100384Speter CP(*in, *out, f_ffree); 133100384Speter CP(*in, *out, f_fsid); 134100384Speter CP(*in, *out, f_owner); 135100384Speter CP(*in, *out, f_type); 136100384Speter CP(*in, *out, f_flags); 137100384Speter CP(*in, *out, f_flags); 138100384Speter CP(*in, *out, f_syncwrites); 139100384Speter CP(*in, *out, f_asyncwrites); 140100384Speter bcopy(in->f_fstypename, 141100384Speter out->f_fstypename, MFSNAMELEN); 142100384Speter bcopy(in->f_mntonname, 143100384Speter out->f_mntonname, MNAMELEN); 144100384Speter CP(*in, *out, f_syncreads); 145100384Speter CP(*in, *out, f_asyncreads); 146100384Speter bcopy(in->f_mntfromname, 147100384Speter out->f_mntfromname, MNAMELEN); 148100384Speter} 149100384Speter 150100384Speterint 151119333Speterfreebsd32_getfsstat(struct thread *td, struct freebsd32_getfsstat_args *uap) 152100384Speter{ 153100384Speter int error; 154100384Speter caddr_t sg; 155100384Speter struct statfs32 *sp32, stat32; 156100384Speter struct statfs *sp = NULL, stat; 157100384Speter int maxcount, count, i; 158100384Speter 159107849Salfred sp32 = uap->buf; 160107849Salfred maxcount = uap->bufsize / sizeof(struct statfs32); 161100384Speter 162100384Speter if (sp32) { 163100384Speter sg = stackgap_init(); 164100384Speter sp = stackgap_alloc(&sg, sizeof(struct statfs) * maxcount); 165107849Salfred uap->buf = (struct statfs32 *)sp; 166100384Speter } 167100384Speter error = getfsstat(td, (struct getfsstat_args *) uap); 168100384Speter if (sp32 && !error) { 169100384Speter count = td->td_retval[0]; 170100384Speter for (i = 0; i < count; i++) { 171100384Speter error = copyin(&sp[i], &stat, sizeof(stat)); 172100384Speter if (error) 173100384Speter return (error); 174100384Speter copy_statfs(&stat, &stat32); 175100384Speter error = copyout(&stat32, &sp32[i], sizeof(stat32)); 176100384Speter if (error) 177100384Speter return (error); 178100384Speter } 179100384Speter } 180100384Speter return (error); 181100384Speter} 182100384Speter 183100384Speterstruct sigaltstack32 { 184100384Speter u_int32_t ss_sp; 185100384Speter u_int32_t ss_size; 186100384Speter int ss_flags; 187100384Speter}; 188100384Speter 189121719SpeterCTASSERT(sizeof(struct sigaltstack32) == 12); 190121719Speter 191100384Speterint 192119333Speterfreebsd32_sigaltstack(struct thread *td, 193119333Speter struct freebsd32_sigaltstack_args *uap) 194100384Speter{ 195113859Sjhb struct sigaltstack32 s32; 196113859Sjhb struct sigaltstack ss, oss, *ssp; 197100384Speter int error; 198100384Speter 199113859Sjhb if (uap->ss != NULL) { 200113859Sjhb error = copyin(uap->ss, &s32, sizeof(s32)); 201100384Speter if (error) 202100384Speter return (error); 203113859Sjhb PTRIN_CP(s32, ss, ss_sp); 204113859Sjhb CP(s32, ss, ss_size); 205113859Sjhb CP(s32, ss, ss_flags); 206113859Sjhb ssp = &ss; 207113859Sjhb } else 208113859Sjhb ssp = NULL; 209113859Sjhb error = kern_sigaltstack(td, ssp, &oss); 210113859Sjhb if (error == 0 && uap->oss != NULL) { 211113859Sjhb PTROUT_CP(oss, s32, ss_sp); 212113859Sjhb CP(oss, s32, ss_size); 213113859Sjhb CP(oss, s32, ss_flags); 214113859Sjhb error = copyout(&s32, uap->oss, sizeof(s32)); 215100384Speter } 216100384Speter return (error); 217100384Speter} 218100384Speter 219100384Speterint 220119333Speterfreebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap) 221100384Speter{ 222100384Speter int error; 223100384Speter caddr_t sg; 224100384Speter struct execve_args ap; 225100384Speter u_int32_t *p32, arg; 226122253Speter char **p, *p64; 227100384Speter int count; 228100384Speter 229100384Speter sg = stackgap_init(); 230107849Salfred ap.fname = uap->fname; 231100384Speter 232107849Salfred if (uap->argv) { 233100384Speter count = 0; 234107849Salfred p32 = uap->argv; 235100384Speter do { 236100384Speter error = copyin(p32++, &arg, sizeof(arg)); 237100384Speter if (error) 238100384Speter return error; 239100384Speter count++; 240100384Speter } while (arg != 0); 241100384Speter p = stackgap_alloc(&sg, count * sizeof(char *)); 242107849Salfred ap.argv = p; 243107849Salfred p32 = uap->argv; 244100384Speter do { 245100384Speter error = copyin(p32++, &arg, sizeof(arg)); 246100384Speter if (error) 247100384Speter return error; 248122253Speter p64 = PTRIN(arg); 249122253Speter error = copyout(&p64, p++, sizeof(p64)); 250122253Speter if (error) 251122253Speter return error; 252100384Speter } while (arg != 0); 253100384Speter } 254107849Salfred if (uap->envv) { 255100384Speter count = 0; 256107849Salfred p32 = uap->envv; 257100384Speter do { 258100384Speter error = copyin(p32++, &arg, sizeof(arg)); 259100384Speter if (error) 260100384Speter return error; 261100384Speter count++; 262100384Speter } while (arg != 0); 263100384Speter p = stackgap_alloc(&sg, count * sizeof(char *)); 264107849Salfred ap.envv = p; 265107849Salfred p32 = uap->envv; 266100384Speter do { 267100384Speter error = copyin(p32++, &arg, sizeof(arg)); 268100384Speter if (error) 269100384Speter return error; 270122253Speter p64 = PTRIN(arg); 271122253Speter error = copyout(&p64, p++, sizeof(p64)); 272122253Speter if (error) 273122253Speter return error; 274100384Speter } while (arg != 0); 275100384Speter } 276100384Speter 277100384Speter return execve(td, &ap); 278100384Speter} 279100384Speter 280114987Speter#ifdef __ia64__ 281100384Speterstatic int 282119333Speterfreebsd32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, 283119333Speter int prot, int fd, off_t pos) 284100384Speter{ 285100384Speter vm_map_t map; 286100384Speter vm_map_entry_t entry; 287100384Speter int rv; 288100384Speter 289100384Speter map = &td->td_proc->p_vmspace->vm_map; 290100384Speter if (fd != -1) 291100384Speter prot |= VM_PROT_WRITE; 292100384Speter 293100384Speter if (vm_map_lookup_entry(map, start, &entry)) { 294100384Speter if ((entry->protection & prot) != prot) { 295100384Speter rv = vm_map_protect(map, 296100384Speter trunc_page(start), 297100384Speter round_page(end), 298100384Speter entry->protection | prot, 299100384Speter FALSE); 300100384Speter if (rv != KERN_SUCCESS) 301100384Speter return (EINVAL); 302100384Speter } 303100384Speter } else { 304100384Speter vm_offset_t addr = trunc_page(start); 305100384Speter rv = vm_map_find(map, 0, 0, 306100384Speter &addr, PAGE_SIZE, FALSE, prot, 307100384Speter VM_PROT_ALL, 0); 308100384Speter if (rv != KERN_SUCCESS) 309100384Speter return (EINVAL); 310100384Speter } 311100384Speter 312100384Speter if (fd != -1) { 313100384Speter struct pread_args r; 314107849Salfred r.fd = fd; 315107849Salfred r.buf = (void *) start; 316107849Salfred r.nbyte = end - start; 317107849Salfred r.offset = pos; 318100384Speter return (pread(td, &r)); 319100384Speter } else { 320100384Speter while (start < end) { 321100384Speter subyte((void *) start, 0); 322100384Speter start++; 323100384Speter } 324100384Speter return (0); 325100384Speter } 326100384Speter} 327114987Speter#endif 328100384Speter 329100384Speterint 330119333Speterfreebsd32_mmap(struct thread *td, struct freebsd32_mmap_args *uap) 331100384Speter{ 332100384Speter struct mmap_args ap; 333107849Salfred vm_offset_t addr = (vm_offset_t) uap->addr; 334107849Salfred vm_size_t len = uap->len; 335107849Salfred int prot = uap->prot; 336107849Salfred int flags = uap->flags; 337107849Salfred int fd = uap->fd; 338107849Salfred off_t pos = (uap->poslo 339107849Salfred | ((off_t)uap->poshi << 32)); 340114987Speter#ifdef __ia64__ 341100384Speter vm_size_t pageoff; 342100384Speter int error; 343100384Speter 344100384Speter /* 345100384Speter * Attempt to handle page size hassles. 346100384Speter */ 347100384Speter pageoff = (pos & PAGE_MASK); 348100384Speter if (flags & MAP_FIXED) { 349100384Speter vm_offset_t start, end; 350100384Speter start = addr; 351100384Speter end = addr + len; 352100384Speter 353100384Speter if (start != trunc_page(start)) { 354119333Speter error = freebsd32_mmap_partial(td, start, 355119333Speter round_page(start), prot, 356119333Speter fd, pos); 357100384Speter if (fd != -1) 358100384Speter pos += round_page(start) - start; 359100384Speter start = round_page(start); 360100384Speter } 361100384Speter if (end != round_page(end)) { 362100384Speter vm_offset_t t = trunc_page(end); 363119333Speter error = freebsd32_mmap_partial(td, t, end, 364100384Speter prot, fd, 365100384Speter pos + t - start); 366100384Speter end = trunc_page(end); 367100384Speter } 368100384Speter if (end > start && fd != -1 && (pos & PAGE_MASK)) { 369100384Speter /* 370100384Speter * We can't map this region at all. The specified 371100384Speter * address doesn't have the same alignment as the file 372100384Speter * position. Fake the mapping by simply reading the 373100384Speter * entire region into memory. First we need to make 374100384Speter * sure the region exists. 375100384Speter */ 376100384Speter vm_map_t map; 377100384Speter struct pread_args r; 378100384Speter int rv; 379100384Speter 380100384Speter prot |= VM_PROT_WRITE; 381100384Speter map = &td->td_proc->p_vmspace->vm_map; 382100384Speter rv = vm_map_remove(map, start, end); 383100384Speter if (rv != KERN_SUCCESS) 384100384Speter return (EINVAL); 385100384Speter rv = vm_map_find(map, 0, 0, 386100384Speter &start, end - start, FALSE, 387100384Speter prot, VM_PROT_ALL, 0); 388100384Speter if (rv != KERN_SUCCESS) 389100384Speter return (EINVAL); 390107849Salfred r.fd = fd; 391107849Salfred r.buf = (void *) start; 392107849Salfred r.nbyte = end - start; 393107849Salfred r.offset = pos; 394100384Speter error = pread(td, &r); 395100384Speter if (error) 396100384Speter return (error); 397100384Speter 398100384Speter td->td_retval[0] = addr; 399100384Speter return (0); 400100384Speter } 401100384Speter if (end == start) { 402100384Speter /* 403100384Speter * After dealing with the ragged ends, there 404100384Speter * might be none left. 405100384Speter */ 406100384Speter td->td_retval[0] = addr; 407100384Speter return (0); 408100384Speter } 409100384Speter addr = start; 410100384Speter len = end - start; 411100384Speter } 412114987Speter#endif 413100384Speter 414107849Salfred ap.addr = (void *) addr; 415107849Salfred ap.len = len; 416107849Salfred ap.prot = prot; 417107849Salfred ap.flags = flags; 418107849Salfred ap.fd = fd; 419107849Salfred ap.pos = pos; 420100384Speter 421100384Speter return (mmap(td, &ap)); 422100384Speter} 423100384Speter 424100384Speterstruct itimerval32 { 425100384Speter struct timeval32 it_interval; 426100384Speter struct timeval32 it_value; 427100384Speter}; 428100384Speter 429121719SpeterCTASSERT(sizeof(struct itimerval32) == 16); 430121719Speter 431100384Speterint 432119333Speterfreebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap) 433100384Speter{ 434100384Speter int error; 435100384Speter caddr_t sg; 436100384Speter struct itimerval32 *p32, *op32, s32; 437100384Speter struct itimerval *p = NULL, *op = NULL, s; 438100384Speter 439107849Salfred p32 = uap->itv; 440100384Speter if (p32) { 441100384Speter sg = stackgap_init(); 442100384Speter p = stackgap_alloc(&sg, sizeof(struct itimerval)); 443107849Salfred uap->itv = (struct itimerval32 *)p; 444100384Speter error = copyin(p32, &s32, sizeof(s32)); 445100384Speter if (error) 446100384Speter return (error); 447100384Speter TV_CP(s32, s, it_interval); 448100384Speter TV_CP(s32, s, it_value); 449100384Speter error = copyout(&s, p, sizeof(s)); 450100384Speter if (error) 451100384Speter return (error); 452100384Speter } 453107849Salfred op32 = uap->oitv; 454100384Speter if (op32) { 455100384Speter sg = stackgap_init(); 456100384Speter op = stackgap_alloc(&sg, sizeof(struct itimerval)); 457107849Salfred uap->oitv = (struct itimerval32 *)op; 458100384Speter } 459100384Speter error = setitimer(td, (struct setitimer_args *) uap); 460100384Speter if (error) 461100384Speter return (error); 462100384Speter if (op32) { 463100384Speter error = copyin(op, &s, sizeof(s)); 464100384Speter if (error) 465100384Speter return (error); 466100384Speter TV_CP(s, s32, it_interval); 467100384Speter TV_CP(s, s32, it_value); 468100384Speter error = copyout(&s32, op32, sizeof(s32)); 469100384Speter } 470100384Speter return (error); 471100384Speter} 472100384Speter 473100384Speterint 474125171Speterfreebsd32_getitimer(struct thread *td, struct freebsd32_getitimer_args *uap) 475125171Speter{ 476125171Speter int error; 477125171Speter caddr_t sg; 478125171Speter struct itimerval32 *p32, s32; 479125171Speter struct itimerval *p = NULL, s; 480125171Speter 481125171Speter p32 = uap->itv; 482125171Speter if (p32) { 483125171Speter sg = stackgap_init(); 484125171Speter p = stackgap_alloc(&sg, sizeof(struct itimerval)); 485125171Speter uap->itv = (struct itimerval32 *)p; 486125171Speter } 487125171Speter error = getitimer(td, (struct getitimer_args *) uap); 488125171Speter if (error) 489125171Speter return (error); 490125171Speter if (p32) { 491125171Speter error = copyin(p, &s, sizeof(s)); 492125171Speter if (error) 493125171Speter return (error); 494125171Speter TV_CP(s, s32, it_interval); 495125171Speter TV_CP(s, s32, it_value); 496125171Speter error = copyout(&s32, p32, sizeof(s32)); 497125171Speter } 498125171Speter return (error); 499125171Speter} 500125171Speter 501125171Speterint 502119333Speterfreebsd32_select(struct thread *td, struct freebsd32_select_args *uap) 503100384Speter{ 504100384Speter int error; 505100384Speter caddr_t sg; 506100384Speter struct timeval32 *p32, s32; 507100384Speter struct timeval *p = NULL, s; 508100384Speter 509107849Salfred p32 = uap->tv; 510100384Speter if (p32) { 511100384Speter sg = stackgap_init(); 512100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 513107849Salfred uap->tv = (struct timeval32 *)p; 514100384Speter error = copyin(p32, &s32, sizeof(s32)); 515100384Speter if (error) 516100384Speter return (error); 517100384Speter CP(s32, s, tv_sec); 518100384Speter CP(s32, s, tv_usec); 519100384Speter error = copyout(&s, p, sizeof(s)); 520100384Speter if (error) 521100384Speter return (error); 522100384Speter } 523100384Speter /* 524100384Speter * XXX big-endian needs to convert the fd_sets too. 525100384Speter */ 526100384Speter return (select(td, (struct select_args *) uap)); 527100384Speter} 528100384Speter 529114987Speterstruct kevent32 { 530114987Speter u_int32_t ident; /* identifier for this event */ 531114987Speter short filter; /* filter for event */ 532114987Speter u_short flags; 533114987Speter u_int fflags; 534114987Speter int32_t data; 535114987Speter u_int32_t udata; /* opaque user data identifier */ 536114987Speter}; 537114987Speter 538121719SpeterCTASSERT(sizeof(struct kevent32) == 20); 539121719Speter 540100384Speterint 541119333Speterfreebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap) 542114987Speter{ 543114987Speter int error; 544114987Speter caddr_t sg; 545114987Speter struct timespec32 ts32; 546114987Speter struct timespec ts; 547114987Speter struct kevent32 ks32; 548114987Speter struct kevent *ks; 549114987Speter struct kevent_args a; 550114987Speter int i; 551114987Speter 552114987Speter sg = stackgap_init(); 553114987Speter 554114987Speter a.fd = uap->fd; 555114987Speter a.changelist = uap->changelist; 556114987Speter a.nchanges = uap->nchanges; 557114987Speter a.eventlist = uap->eventlist; 558114987Speter a.nevents = uap->nevents; 559114987Speter a.timeout = NULL; 560114987Speter 561114987Speter if (uap->timeout) { 562114987Speter a.timeout = stackgap_alloc(&sg, sizeof(struct timespec)); 563114987Speter error = copyin(uap->timeout, &ts32, sizeof(ts32)); 564114987Speter if (error) 565114987Speter return (error); 566114987Speter CP(ts32, ts, tv_sec); 567114987Speter CP(ts32, ts, tv_nsec); 568114987Speter error = copyout(&ts, (void *)(uintptr_t)a.timeout, sizeof(ts)); 569114987Speter if (error) 570114987Speter return (error); 571114987Speter } 572114987Speter if (uap->changelist) { 573119333Speter a.changelist = (struct kevent *)stackgap_alloc(&sg, 574119333Speter uap->nchanges * sizeof(struct kevent)); 575114987Speter for (i = 0; i < uap->nchanges; i++) { 576119333Speter error = copyin(&uap->changelist[i], &ks32, 577119333Speter sizeof(ks32)); 578114987Speter if (error) 579114987Speter return (error); 580114987Speter ks = (struct kevent *)(uintptr_t)&a.changelist[i]; 581114987Speter CP(ks32, *ks, ident); 582114987Speter CP(ks32, *ks, filter); 583114987Speter CP(ks32, *ks, flags); 584114987Speter CP(ks32, *ks, fflags); 585114987Speter CP(ks32, *ks, data); 586114987Speter PTRIN_CP(ks32, *ks, udata); 587114987Speter } 588114987Speter } 589114987Speter if (uap->eventlist) { 590119333Speter a.eventlist = stackgap_alloc(&sg, 591119333Speter uap->nevents * sizeof(struct kevent)); 592114987Speter } 593114987Speter error = kevent(td, &a); 594114987Speter if (uap->eventlist && error > 0) { 595114987Speter for (i = 0; i < error; i++) { 596114987Speter ks = &a.eventlist[i]; 597114987Speter CP(*ks, ks32, ident); 598114987Speter CP(*ks, ks32, filter); 599114987Speter CP(*ks, ks32, flags); 600114987Speter CP(*ks, ks32, fflags); 601114987Speter CP(*ks, ks32, data); 602114987Speter PTROUT_CP(*ks, ks32, udata); 603119333Speter error = copyout(&ks32, &uap->eventlist[i], 604119333Speter sizeof(ks32)); 605114987Speter if (error) 606114987Speter return (error); 607114987Speter } 608114987Speter } 609114987Speter return error; 610114987Speter} 611114987Speter 612114987Speterint 613119333Speterfreebsd32_gettimeofday(struct thread *td, 614119333Speter struct freebsd32_gettimeofday_args *uap) 615100384Speter{ 616123425Speter struct timeval atv; 617123425Speter struct timeval32 atv32; 618123425Speter struct timezone rtz; 619123425Speter int error = 0; 620100384Speter 621123425Speter if (uap->tp) { 622123425Speter microtime(&atv); 623123425Speter CP(atv, atv32, tv_sec); 624123425Speter CP(atv, atv32, tv_usec); 625123425Speter error = copyout(&atv32, uap->tp, sizeof (atv32)); 626100384Speter } 627123425Speter if (error == 0 && uap->tzp != NULL) { 628123425Speter rtz.tz_minuteswest = tz_minuteswest; 629123425Speter rtz.tz_dsttime = tz_dsttime; 630123425Speter error = copyout(&rtz, uap->tzp, sizeof (rtz)); 631100384Speter } 632100384Speter return (error); 633100384Speter} 634100384Speter 635100384Speterint 636119333Speterfreebsd32_getrusage(struct thread *td, struct freebsd32_getrusage_args *uap) 637100384Speter{ 638100384Speter int error; 639100384Speter caddr_t sg; 640100384Speter struct rusage32 *p32, s32; 641100384Speter struct rusage *p = NULL, s; 642100384Speter 643107849Salfred p32 = uap->rusage; 644100384Speter if (p32) { 645100384Speter sg = stackgap_init(); 646100384Speter p = stackgap_alloc(&sg, sizeof(struct rusage)); 647107849Salfred uap->rusage = (struct rusage32 *)p; 648100384Speter } 649100384Speter error = getrusage(td, (struct getrusage_args *) uap); 650100384Speter if (error) 651100384Speter return (error); 652100384Speter if (p32) { 653100384Speter error = copyin(p, &s, sizeof(s)); 654100384Speter if (error) 655100384Speter return (error); 656100384Speter TV_CP(s, s32, ru_utime); 657100384Speter TV_CP(s, s32, ru_stime); 658100384Speter CP(s, s32, ru_maxrss); 659100384Speter CP(s, s32, ru_ixrss); 660100384Speter CP(s, s32, ru_idrss); 661100384Speter CP(s, s32, ru_isrss); 662100384Speter CP(s, s32, ru_minflt); 663100384Speter CP(s, s32, ru_majflt); 664100384Speter CP(s, s32, ru_nswap); 665100384Speter CP(s, s32, ru_inblock); 666100384Speter CP(s, s32, ru_oublock); 667100384Speter CP(s, s32, ru_msgsnd); 668100384Speter CP(s, s32, ru_msgrcv); 669100384Speter CP(s, s32, ru_nsignals); 670100384Speter CP(s, s32, ru_nvcsw); 671100384Speter CP(s, s32, ru_nivcsw); 672100384Speter error = copyout(&s32, p32, sizeof(s32)); 673100384Speter } 674100384Speter return (error); 675100384Speter} 676100384Speter 677100384Speterstruct iovec32 { 678100384Speter u_int32_t iov_base; 679100384Speter int iov_len; 680100384Speter}; 681100384Speter#define STACKGAPLEN 400 682100384Speter 683121719SpeterCTASSERT(sizeof(struct iovec32) == 8); 684121719Speter 685100384Speterint 686119333Speterfreebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap) 687100384Speter{ 688100384Speter int error, osize, nsize, i; 689100384Speter caddr_t sg; 690100384Speter struct readv_args /* { 691100384Speter syscallarg(int) fd; 692100384Speter syscallarg(struct iovec *) iovp; 693100384Speter syscallarg(u_int) iovcnt; 694100384Speter } */ a; 695100384Speter struct iovec32 *oio; 696100384Speter struct iovec *nio; 697100384Speter 698100384Speter sg = stackgap_init(); 699100384Speter 700107849Salfred if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 701100384Speter return (EINVAL); 702100384Speter 703107849Salfred osize = uap->iovcnt * sizeof (struct iovec32); 704107849Salfred nsize = uap->iovcnt * sizeof (struct iovec); 705100384Speter 706111119Simp oio = malloc(osize, M_TEMP, M_WAITOK); 707111119Simp nio = malloc(nsize, M_TEMP, M_WAITOK); 708100384Speter 709100384Speter error = 0; 710107849Salfred if ((error = copyin(uap->iovp, oio, osize))) 711100384Speter goto punt; 712107849Salfred for (i = 0; i < uap->iovcnt; i++) { 713100384Speter nio[i].iov_base = PTRIN(oio[i].iov_base); 714100384Speter nio[i].iov_len = oio[i].iov_len; 715100384Speter } 716100384Speter 717107849Salfred a.fd = uap->fd; 718107849Salfred a.iovp = stackgap_alloc(&sg, nsize); 719107849Salfred a.iovcnt = uap->iovcnt; 720100384Speter 721107849Salfred if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 722100384Speter goto punt; 723100384Speter error = readv(td, &a); 724100384Speter 725100384Speterpunt: 726100384Speter free(oio, M_TEMP); 727100384Speter free(nio, M_TEMP); 728100384Speter return (error); 729100384Speter} 730100384Speter 731100384Speterint 732119333Speterfreebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap) 733100384Speter{ 734100384Speter int error, i, nsize, osize; 735100384Speter caddr_t sg; 736100384Speter struct writev_args /* { 737100384Speter syscallarg(int) fd; 738100384Speter syscallarg(struct iovec *) iovp; 739100384Speter syscallarg(u_int) iovcnt; 740100384Speter } */ a; 741100384Speter struct iovec32 *oio; 742100384Speter struct iovec *nio; 743100384Speter 744100384Speter sg = stackgap_init(); 745100384Speter 746107849Salfred if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec))) 747100384Speter return (EINVAL); 748100384Speter 749107849Salfred osize = uap->iovcnt * sizeof (struct iovec32); 750107849Salfred nsize = uap->iovcnt * sizeof (struct iovec); 751100384Speter 752111119Simp oio = malloc(osize, M_TEMP, M_WAITOK); 753111119Simp nio = malloc(nsize, M_TEMP, M_WAITOK); 754100384Speter 755100384Speter error = 0; 756107849Salfred if ((error = copyin(uap->iovp, oio, osize))) 757100384Speter goto punt; 758107849Salfred for (i = 0; i < uap->iovcnt; i++) { 759100384Speter nio[i].iov_base = PTRIN(oio[i].iov_base); 760100384Speter nio[i].iov_len = oio[i].iov_len; 761100384Speter } 762100384Speter 763107849Salfred a.fd = uap->fd; 764107849Salfred a.iovp = stackgap_alloc(&sg, nsize); 765107849Salfred a.iovcnt = uap->iovcnt; 766100384Speter 767107849Salfred if ((error = copyout(nio, (caddr_t)a.iovp, nsize))) 768100384Speter goto punt; 769100384Speter error = writev(td, &a); 770100384Speter 771100384Speterpunt: 772100384Speter free(oio, M_TEMP); 773100384Speter free(nio, M_TEMP); 774100384Speter return (error); 775100384Speter} 776100384Speter 777100384Speterint 778119333Speterfreebsd32_settimeofday(struct thread *td, 779119333Speter struct freebsd32_settimeofday_args *uap) 780100384Speter{ 781100384Speter int error; 782100384Speter caddr_t sg; 783100384Speter struct timeval32 *p32, s32; 784100384Speter struct timeval *p = NULL, s; 785100384Speter 786107849Salfred p32 = uap->tv; 787100384Speter if (p32) { 788100384Speter sg = stackgap_init(); 789100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 790107849Salfred uap->tv = (struct timeval32 *)p; 791100384Speter error = copyin(p32, &s32, sizeof(s32)); 792100384Speter if (error) 793100384Speter return (error); 794100384Speter CP(s32, s, tv_sec); 795100384Speter CP(s32, s, tv_usec); 796100384Speter error = copyout(&s, p, sizeof(s)); 797100384Speter if (error) 798100384Speter return (error); 799100384Speter } 800100384Speter return (settimeofday(td, (struct settimeofday_args *) uap)); 801100384Speter} 802100384Speter 803100384Speterint 804119333Speterfreebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap) 805100384Speter{ 806100384Speter int error; 807100384Speter caddr_t sg; 808100384Speter struct timeval32 *p32, s32[2]; 809100384Speter struct timeval *p = NULL, s[2]; 810100384Speter 811107849Salfred p32 = uap->tptr; 812100384Speter if (p32) { 813100384Speter sg = stackgap_init(); 814100384Speter p = stackgap_alloc(&sg, 2*sizeof(struct timeval)); 815107849Salfred uap->tptr = (struct timeval32 *)p; 816100384Speter error = copyin(p32, s32, sizeof(s32)); 817100384Speter if (error) 818100384Speter return (error); 819100384Speter CP(s32[0], s[0], tv_sec); 820100384Speter CP(s32[0], s[0], tv_usec); 821100384Speter CP(s32[1], s[1], tv_sec); 822100384Speter CP(s32[1], s[1], tv_usec); 823100384Speter error = copyout(s, p, sizeof(s)); 824100384Speter if (error) 825100384Speter return (error); 826100384Speter } 827100384Speter return (utimes(td, (struct utimes_args *) uap)); 828100384Speter} 829100384Speter 830100384Speterint 831119333Speterfreebsd32_adjtime(struct thread *td, struct freebsd32_adjtime_args *uap) 832100384Speter{ 833100384Speter int error; 834100384Speter caddr_t sg; 835100384Speter struct timeval32 *p32, *op32, s32; 836100384Speter struct timeval *p = NULL, *op = NULL, s; 837100384Speter 838107849Salfred p32 = uap->delta; 839100384Speter if (p32) { 840100384Speter sg = stackgap_init(); 841100384Speter p = stackgap_alloc(&sg, sizeof(struct timeval)); 842107849Salfred uap->delta = (struct timeval32 *)p; 843100384Speter error = copyin(p32, &s32, sizeof(s32)); 844100384Speter if (error) 845100384Speter return (error); 846100384Speter CP(s32, s, tv_sec); 847100384Speter CP(s32, s, tv_usec); 848100384Speter error = copyout(&s, p, sizeof(s)); 849100384Speter if (error) 850100384Speter return (error); 851100384Speter } 852107849Salfred op32 = uap->olddelta; 853100384Speter if (op32) { 854100384Speter sg = stackgap_init(); 855100384Speter op = stackgap_alloc(&sg, sizeof(struct timeval)); 856107849Salfred uap->olddelta = (struct timeval32 *)op; 857100384Speter } 858100384Speter error = utimes(td, (struct utimes_args *) uap); 859100384Speter if (error) 860100384Speter return error; 861100384Speter if (op32) { 862100384Speter error = copyin(op, &s, sizeof(s)); 863100384Speter if (error) 864100384Speter return (error); 865100384Speter CP(s, s32, tv_sec); 866100384Speter CP(s, s32, tv_usec); 867100384Speter error = copyout(&s32, op32, sizeof(s32)); 868100384Speter } 869100384Speter return (error); 870100384Speter} 871100384Speter 872100384Speterint 873119333Speterfreebsd32_statfs(struct thread *td, struct freebsd32_statfs_args *uap) 874100384Speter{ 875100384Speter int error; 876100384Speter caddr_t sg; 877100384Speter struct statfs32 *p32, s32; 878100384Speter struct statfs *p = NULL, s; 879100384Speter 880107849Salfred p32 = uap->buf; 881100384Speter if (p32) { 882100384Speter sg = stackgap_init(); 883100384Speter p = stackgap_alloc(&sg, sizeof(struct statfs)); 884107849Salfred uap->buf = (struct statfs32 *)p; 885100384Speter } 886100384Speter error = statfs(td, (struct statfs_args *) uap); 887100384Speter if (error) 888100384Speter return (error); 889100384Speter if (p32) { 890100384Speter error = copyin(p, &s, sizeof(s)); 891100384Speter if (error) 892100384Speter return (error); 893100384Speter copy_statfs(&s, &s32); 894100384Speter error = copyout(&s32, p32, sizeof(s32)); 895100384Speter } 896100384Speter return (error); 897100384Speter} 898100384Speter 899100384Speterint 900119333Speterfreebsd32_fstatfs(struct thread *td, struct freebsd32_fstatfs_args *uap) 901100384Speter{ 902100384Speter int error; 903100384Speter caddr_t sg; 904100384Speter struct statfs32 *p32, s32; 905100384Speter struct statfs *p = NULL, s; 906100384Speter 907107849Salfred p32 = uap->buf; 908100384Speter if (p32) { 909100384Speter sg = stackgap_init(); 910100384Speter p = stackgap_alloc(&sg, sizeof(struct statfs)); 911107849Salfred uap->buf = (struct statfs32 *)p; 912100384Speter } 913100384Speter error = fstatfs(td, (struct fstatfs_args *) uap); 914100384Speter if (error) 915100384Speter return (error); 916100384Speter if (p32) { 917100384Speter error = copyin(p, &s, sizeof(s)); 918100384Speter if (error) 919100384Speter return (error); 920100384Speter copy_statfs(&s, &s32); 921100384Speter error = copyout(&s32, p32, sizeof(s32)); 922100384Speter } 923100384Speter return (error); 924100384Speter} 925100384Speter 926100384Speterint 927119333Speterfreebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap) 928100384Speter{ 929100384Speter /* 930100384Speter * Vector through to semsys if it is loaded. 931100384Speter */ 932100384Speter return sysent[169].sy_call(td, uap); 933100384Speter} 934100384Speter 935100384Speterint 936119333Speterfreebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap) 937100384Speter{ 938100384Speter /* 939100384Speter * Vector through to msgsys if it is loaded. 940100384Speter */ 941100384Speter return sysent[170].sy_call(td, uap); 942100384Speter} 943100384Speter 944100384Speterint 945119333Speterfreebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap) 946100384Speter{ 947100384Speter /* 948100384Speter * Vector through to shmsys if it is loaded. 949100384Speter */ 950100384Speter return sysent[171].sy_call(td, uap); 951100384Speter} 952100384Speter 953100384Speterint 954119333Speterfreebsd32_pread(struct thread *td, struct freebsd32_pread_args *uap) 955100384Speter{ 956100384Speter struct pread_args ap; 957100384Speter 958107849Salfred ap.fd = uap->fd; 959107849Salfred ap.buf = uap->buf; 960107849Salfred ap.nbyte = uap->nbyte; 961119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 962100384Speter return (pread(td, &ap)); 963100384Speter} 964100384Speter 965100384Speterint 966119333Speterfreebsd32_pwrite(struct thread *td, struct freebsd32_pwrite_args *uap) 967100384Speter{ 968100384Speter struct pwrite_args ap; 969100384Speter 970107849Salfred ap.fd = uap->fd; 971107849Salfred ap.buf = uap->buf; 972107849Salfred ap.nbyte = uap->nbyte; 973119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 974100384Speter return (pwrite(td, &ap)); 975100384Speter} 976100384Speter 977100384Speterint 978119333Speterfreebsd32_lseek(struct thread *td, struct freebsd32_lseek_args *uap) 979100384Speter{ 980100384Speter int error; 981100384Speter struct lseek_args ap; 982100384Speter off_t pos; 983100384Speter 984107849Salfred ap.fd = uap->fd; 985119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 986107849Salfred ap.whence = uap->whence; 987100384Speter error = lseek(td, &ap); 988100384Speter /* Expand the quad return into two parts for eax and edx */ 989100384Speter pos = *(off_t *)(td->td_retval); 990100384Speter td->td_retval[0] = pos & 0xffffffff; /* %eax */ 991100384Speter td->td_retval[1] = pos >> 32; /* %edx */ 992100384Speter return error; 993100384Speter} 994100384Speter 995100384Speterint 996119333Speterfreebsd32_truncate(struct thread *td, struct freebsd32_truncate_args *uap) 997100384Speter{ 998100384Speter struct truncate_args ap; 999100384Speter 1000107849Salfred ap.path = uap->path; 1001119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1002100384Speter return (truncate(td, &ap)); 1003100384Speter} 1004100384Speter 1005100384Speterint 1006119333Speterfreebsd32_ftruncate(struct thread *td, struct freebsd32_ftruncate_args *uap) 1007100384Speter{ 1008100384Speter struct ftruncate_args ap; 1009100384Speter 1010107849Salfred ap.fd = uap->fd; 1011119333Speter ap.length = (uap->lengthlo | ((off_t)uap->lengthhi << 32)); 1012100384Speter return (ftruncate(td, &ap)); 1013100384Speter} 1014100384Speter 1015104738Speter#ifdef COMPAT_FREEBSD4 1016100384Speterint 1017119333Speterfreebsd4_freebsd32_sendfile(struct thread *td, 1018119333Speter struct freebsd4_freebsd32_sendfile_args *uap) 1019104738Speter{ 1020104738Speter struct freebsd4_sendfile_args ap; 1021104738Speter 1022107849Salfred ap.fd = uap->fd; 1023107849Salfred ap.s = uap->s; 1024119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1025107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1026107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1027107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1028107849Salfred ap.flags = uap->flags; 1029104738Speter return (freebsd4_sendfile(td, &ap)); 1030104738Speter} 1031104738Speter#endif 1032104738Speter 1033104738Speterint 1034119333Speterfreebsd32_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap) 1035100384Speter{ 1036100384Speter struct sendfile_args ap; 1037100384Speter 1038107849Salfred ap.fd = uap->fd; 1039107849Salfred ap.s = uap->s; 1040119333Speter ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32)); 1041107849Salfred ap.nbytes = uap->nbytes; /* XXX check */ 1042107849Salfred ap.hdtr = uap->hdtr; /* XXX check */ 1043107849Salfred ap.sbytes = uap->sbytes; /* XXX FIXME!! */ 1044107849Salfred ap.flags = uap->flags; 1045100384Speter return (sendfile(td, &ap)); 1046100384Speter} 1047100384Speter 1048100384Speterstruct stat32 { 1049100384Speter udev_t st_dev; 1050100384Speter ino_t st_ino; 1051100384Speter mode_t st_mode; 1052100384Speter nlink_t st_nlink; 1053100384Speter uid_t st_uid; 1054100384Speter gid_t st_gid; 1055100384Speter udev_t st_rdev; 1056100384Speter struct timespec32 st_atimespec; 1057100384Speter struct timespec32 st_mtimespec; 1058100384Speter struct timespec32 st_ctimespec; 1059100384Speter off_t st_size; 1060100384Speter int64_t st_blocks; 1061100384Speter u_int32_t st_blksize; 1062100384Speter u_int32_t st_flags; 1063100384Speter u_int32_t st_gen; 1064121719Speter struct timespec32 st_birthtimespec; 1065121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1066121719Speter unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); 1067100384Speter}; 1068100384Speter 1069121719Speter 1070121719SpeterCTASSERT(sizeof(struct stat32) == 96); 1071121719Speter 1072100384Speterstatic void 1073100384Spetercopy_stat( struct stat *in, struct stat32 *out) 1074100384Speter{ 1075100384Speter CP(*in, *out, st_dev); 1076100384Speter CP(*in, *out, st_ino); 1077100384Speter CP(*in, *out, st_mode); 1078100384Speter CP(*in, *out, st_nlink); 1079100384Speter CP(*in, *out, st_uid); 1080100384Speter CP(*in, *out, st_gid); 1081100384Speter CP(*in, *out, st_rdev); 1082100384Speter TS_CP(*in, *out, st_atimespec); 1083100384Speter TS_CP(*in, *out, st_mtimespec); 1084100384Speter TS_CP(*in, *out, st_ctimespec); 1085100384Speter CP(*in, *out, st_size); 1086100384Speter CP(*in, *out, st_blocks); 1087100384Speter CP(*in, *out, st_blksize); 1088100384Speter CP(*in, *out, st_flags); 1089100384Speter CP(*in, *out, st_gen); 1090100384Speter} 1091100384Speter 1092100384Speterint 1093119333Speterfreebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap) 1094100384Speter{ 1095123746Speter struct stat sb; 1096123746Speter struct stat32 sb32; 1097100384Speter int error; 1098123746Speter struct nameidata nd; 1099100384Speter 1100123746Speter#ifdef LOOKUP_SHARED 1101123746Speter NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | NOOBJ, 1102123746Speter UIO_USERSPACE, uap->path, td); 1103123746Speter#else 1104123746Speter NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1105123746Speter uap->path, td); 1106123746Speter#endif 1107123746Speter if ((error = namei(&nd)) != 0) 1108123746Speter return (error); 1109123746Speter error = vn_stat(nd.ni_vp, &sb, td->td_ucred, NOCRED, td); 1110123746Speter NDFREE(&nd, NDF_ONLY_PNBUF); 1111123746Speter vput(nd.ni_vp); 1112100384Speter if (error) 1113100384Speter return (error); 1114123746Speter copy_stat(&sb, &sb32); 1115123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1116100384Speter return (error); 1117100384Speter} 1118100384Speter 1119100384Speterint 1120119333Speterfreebsd32_fstat(struct thread *td, struct freebsd32_fstat_args *uap) 1121100384Speter{ 1122123746Speter struct file *fp; 1123123746Speter struct stat ub; 1124123746Speter struct stat32 ub32; 1125100384Speter int error; 1126100384Speter 1127123746Speter if ((error = fget(td, uap->fd, &fp)) != 0) 1128123746Speter return (error); 1129123746Speter mtx_lock(&Giant); 1130123746Speter error = fo_stat(fp, &ub, td->td_ucred, td); 1131123746Speter mtx_unlock(&Giant); 1132123746Speter fdrop(fp, td); 1133100384Speter if (error) 1134100384Speter return (error); 1135123746Speter copy_stat(&ub, &ub32); 1136123746Speter error = copyout(&ub32, uap->ub, sizeof(ub32)); 1137100384Speter return (error); 1138100384Speter} 1139100384Speter 1140100384Speterint 1141119333Speterfreebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap) 1142100384Speter{ 1143100384Speter int error; 1144123746Speter struct vnode *vp; 1145123746Speter struct stat sb; 1146123746Speter struct stat32 sb32; 1147123746Speter struct nameidata nd; 1148100384Speter 1149123746Speter NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE, 1150123746Speter uap->path, td); 1151123746Speter if ((error = namei(&nd)) != 0) 1152123746Speter return (error); 1153123746Speter vp = nd.ni_vp; 1154123746Speter error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td); 1155123746Speter NDFREE(&nd, NDF_ONLY_PNBUF); 1156123746Speter vput(vp); 1157100384Speter if (error) 1158100384Speter return (error); 1159123746Speter copy_stat(&sb, &sb32); 1160123746Speter error = copyout(&sb32, uap->ub, sizeof (sb32)); 1161100384Speter return (error); 1162100384Speter} 1163100384Speter 1164100384Speter/* 1165100384Speter * MPSAFE 1166100384Speter */ 1167100384Speterint 1168119333Speterfreebsd32_sysctl(struct thread *td, struct freebsd32_sysctl_args *uap) 1169100384Speter{ 1170100384Speter int error, name[CTL_MAXNAME]; 1171100384Speter size_t j, oldlen; 1172100384Speter 1173100384Speter if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 1174100384Speter return (EINVAL); 1175100384Speter 1176100384Speter error = copyin(uap->name, &name, uap->namelen * sizeof(int)); 1177100384Speter if (error) 1178100384Speter return (error); 1179100384Speter 1180100384Speter mtx_lock(&Giant); 1181100384Speter 1182100384Speter if (uap->oldlenp) 1183100384Speter oldlen = fuword32(uap->oldlenp); 1184100384Speter else 1185100384Speter oldlen = 0; 1186100384Speter error = userland_sysctl(td, name, uap->namelen, 1187100384Speter uap->old, &oldlen, 1, 1188100384Speter uap->new, uap->newlen, &j); 1189100384Speter if (error && error != ENOMEM) 1190100384Speter goto done2; 1191100384Speter if (uap->oldlenp) { 1192100384Speter suword32(uap->oldlenp, j); 1193100384Speter } 1194100384Speterdone2: 1195100384Speter mtx_unlock(&Giant); 1196100384Speter return (error); 1197100384Speter} 1198100384Speter 1199100384Speterstruct sigaction32 { 1200100384Speter u_int32_t sa_u; 1201100384Speter int sa_flags; 1202100384Speter sigset_t sa_mask; 1203100384Speter}; 1204100384Speter 1205121719SpeterCTASSERT(sizeof(struct sigaction32) == 24); 1206121719Speter 1207100384Speterint 1208119333Speterfreebsd32_sigaction(struct thread *td, struct freebsd32_sigaction_args *uap) 1209100384Speter{ 1210113859Sjhb struct sigaction32 s32; 1211113859Sjhb struct sigaction sa, osa, *sap; 1212100384Speter int error; 1213100384Speter 1214113859Sjhb if (uap->act) { 1215113859Sjhb error = copyin(uap->act, &s32, sizeof(s32)); 1216100384Speter if (error) 1217100384Speter return (error); 1218113859Sjhb sa.sa_handler = PTRIN(s32.sa_u); 1219113859Sjhb CP(s32, sa, sa_flags); 1220113859Sjhb CP(s32, sa, sa_mask); 1221113859Sjhb sap = &sa; 1222113859Sjhb } else 1223113859Sjhb sap = NULL; 1224113859Sjhb error = kern_sigaction(td, uap->sig, sap, &osa, 0); 1225113859Sjhb if (error != 0 && uap->oact != NULL) { 1226113859Sjhb s32.sa_u = PTROUT(osa.sa_handler); 1227113859Sjhb CP(osa, s32, sa_flags); 1228113859Sjhb CP(osa, s32, sa_mask); 1229113859Sjhb error = copyout(&s32, uap->oact, sizeof(s32)); 1230100384Speter } 1231100384Speter return (error); 1232100384Speter} 1233100384Speter 1234114987Speter#ifdef COMPAT_FREEBSD4 1235114987Speterint 1236119333Speterfreebsd4_freebsd32_sigaction(struct thread *td, 1237119333Speter struct freebsd4_freebsd32_sigaction_args *uap) 1238114987Speter{ 1239114987Speter struct sigaction32 s32; 1240114987Speter struct sigaction sa, osa, *sap; 1241114987Speter int error; 1242114987Speter 1243114987Speter if (uap->act) { 1244114987Speter error = copyin(uap->act, &s32, sizeof(s32)); 1245114987Speter if (error) 1246114987Speter return (error); 1247114987Speter sa.sa_handler = PTRIN(s32.sa_u); 1248114987Speter CP(s32, sa, sa_flags); 1249114987Speter CP(s32, sa, sa_mask); 1250114987Speter sap = &sa; 1251114987Speter } else 1252114987Speter sap = NULL; 1253114987Speter error = kern_sigaction(td, uap->sig, sap, &osa, KSA_FREEBSD4); 1254114987Speter if (error != 0 && uap->oact != NULL) { 1255114987Speter s32.sa_u = PTROUT(osa.sa_handler); 1256114987Speter CP(osa, s32, sa_flags); 1257114987Speter CP(osa, s32, sa_mask); 1258114987Speter error = copyout(&s32, uap->oact, sizeof(s32)); 1259114987Speter } 1260114987Speter return (error); 1261114987Speter} 1262114987Speter#endif 1263114987Speter 1264100384Speter#if 0 1265100384Speter 1266100384Speterint 1267119333Speterfreebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) 1268100384Speter{ 1269100384Speter int error; 1270100384Speter caddr_t sg; 1271100384Speter struct yyy32 *p32, s32; 1272100384Speter struct yyy *p = NULL, s; 1273100384Speter 1274107849Salfred p32 = uap->zzz; 1275100384Speter if (p32) { 1276100384Speter sg = stackgap_init(); 1277100384Speter p = stackgap_alloc(&sg, sizeof(struct yyy)); 1278107849Salfred uap->zzz = (struct yyy32 *)p; 1279100384Speter error = copyin(p32, &s32, sizeof(s32)); 1280100384Speter if (error) 1281100384Speter return (error); 1282100384Speter /* translate in */ 1283100384Speter error = copyout(&s, p, sizeof(s)); 1284100384Speter if (error) 1285100384Speter return (error); 1286100384Speter } 1287100384Speter error = xxx(td, (struct xxx_args *) uap); 1288100384Speter if (error) 1289100384Speter return (error); 1290100384Speter if (p32) { 1291100384Speter error = copyin(p, &s, sizeof(s)); 1292100384Speter if (error) 1293100384Speter return (error); 1294100384Speter /* translate out */ 1295100384Speter error = copyout(&s32, p32, sizeof(s32)); 1296100384Speter } 1297100384Speter return (error); 1298100384Speter} 1299100384Speter 1300100384Speter#endif 1301