linux_misc.c revision 12689
19313Ssos/*- 29313Ssos * Copyright (c) 1994-1995 S�ren Schmidt 39313Ssos * All rights reserved. 49313Ssos * 59313Ssos * Redistribution and use in source and binary forms, with or without 69313Ssos * modification, are permitted provided that the following conditions 79313Ssos * are met: 89313Ssos * 1. Redistributions of source code must retain the above copyright 99313Ssos * notice, this list of conditions and the following disclaimer 109313Ssos * in this position and unchanged. 119313Ssos * 2. Redistributions in binary form must reproduce the above copyright 129313Ssos * notice, this list of conditions and the following disclaimer in the 139313Ssos * documentation and/or other materials provided with the distribution. 149313Ssos * 3. The name of the author may not be used to endorse or promote products 159313Ssos * derived from this software withough specific prior written permission 169313Ssos * 179313Ssos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 189313Ssos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 199313Ssos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 209313Ssos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 219313Ssos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 229313Ssos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 239313Ssos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 249313Ssos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 259313Ssos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 269313Ssos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 279313Ssos * 2812689Speter * $Id: linux_misc.c,v 1.5 1995/12/06 19:14:16 bde Exp $ 299313Ssos */ 309313Ssos 319313Ssos#include <sys/param.h> 329313Ssos#include <sys/systm.h> 3312458Sbde#include <sys/sysproto.h> 3412458Sbde#include <sys/kernel.h> 359313Ssos#include <sys/exec.h> 369313Ssos#include <sys/mman.h> 379313Ssos#include <sys/proc.h> 389313Ssos#include <sys/dirent.h> 399313Ssos#include <sys/file.h> 409313Ssos#include <sys/filedesc.h> 419313Ssos#include <sys/ioctl.h> 429313Ssos#include <sys/imgact_aout.h> 439313Ssos#include <sys/mount.h> 449313Ssos#include <sys/namei.h> 459313Ssos#include <sys/resource.h> 469313Ssos#include <sys/resourcevar.h> 479313Ssos#include <sys/stat.h> 4812458Sbde#include <sys/sysctl.h> 499313Ssos#include <sys/times.h> 509313Ssos#include <sys/utsname.h> 519313Ssos#include <sys/vnode.h> 529313Ssos#include <sys/wait.h> 539313Ssos 5412652Sbde#include <vm/vm.h> 5512689Speter#include <vm/vm_param.h> 5612689Speter#include <vm/pmap.h> 5712689Speter#include <vm/lock.h> 5812458Sbde#include <vm/vm_kern.h> 5912689Speter#include <vm/vm_prot.h> 6012689Speter#include <vm/vm_map.h> 6112458Sbde 629313Ssos#include <machine/cpu.h> 639313Ssos#include <machine/psl.h> 649313Ssos 6512458Sbde#include <i386/linux/linux.h> 6612458Sbde#include <i386/linux/sysproto.h> 679313Ssos 689313Ssosstruct linux_alarm_args { 699313Ssos unsigned int secs; 709313Ssos}; 719313Ssos 729313Ssosint 739313Ssoslinux_alarm(struct proc *p, struct linux_alarm_args *args, int *retval) 749313Ssos{ 759313Ssos struct itimerval it, old_it; 769313Ssos int s; 779313Ssos 789313Ssos#ifdef DEBUG 799313Ssos printf("Linux-emul(%d): alarm(%d)\n", p->p_pid, args->secs); 809313Ssos#endif 819313Ssos it.it_value.tv_sec = (long)args->secs; 829313Ssos it.it_value.tv_usec = 0; 839313Ssos it.it_interval.tv_sec = 0; 849313Ssos it.it_interval.tv_usec = 0; 859313Ssos s = splclock(); 869313Ssos old_it = p->p_realtimer; 879313Ssos if (timerisset(&old_it.it_value)) 889313Ssos if (timercmp(&old_it.it_value, &time, <)) 899313Ssos timerclear(&old_it.it_value); 909313Ssos else 919313Ssos timevalsub(&old_it.it_value, &time); 929313Ssos splx(s); 939313Ssos if (itimerfix(&it.it_value) || itimerfix(&it.it_interval)) 949313Ssos return EINVAL; 959313Ssos s = splclock(); 969313Ssos untimeout(realitexpire, (caddr_t)p); 979313Ssos if (timerisset(&it.it_value)) { 989313Ssos timevaladd(&it.it_value, &time); 999313Ssos timeout(realitexpire, (caddr_t)p, hzto(&it.it_value)); 1009313Ssos } 1019313Ssos p->p_realtimer = it; 1029313Ssos splx(s); 1039313Ssos if (old_it.it_value.tv_usec) 1049313Ssos old_it.it_value.tv_sec++; 1059313Ssos *retval = old_it.it_value.tv_sec; 1069313Ssos return 0; 1079313Ssos} 1089313Ssos 1099313Ssosstruct linux_brk_args { 1109313Ssos linux_caddr_t dsend; 1119313Ssos}; 1129313Ssos 1139313Ssosint 1149313Ssoslinux_brk(struct proc *p, struct linux_brk_args *args, int *retval) 1159313Ssos{ 1169313Ssos#if 0 1179313Ssos struct vmspace *vm = p->p_vmspace; 1189313Ssos vm_offset_t new, old; 1199313Ssos int error; 1209313Ssos 1219313Ssos if ((vm_offset_t)args->dsend < (vm_offset_t)vm->vm_daddr) 1229313Ssos return EINVAL; 1239313Ssos if (((caddr_t)args->dsend - (caddr_t)vm->vm_daddr) 1249313Ssos > p->p_rlimit[RLIMIT_DATA].rlim_cur) 1259313Ssos return ENOMEM; 1269313Ssos 1279313Ssos old = round_page((vm_offset_t)vm->vm_daddr) + ctob(vm->vm_dsize); 1289313Ssos new = round_page((vm_offset_t)args->dsend); 1299313Ssos *retval = old; 1309313Ssos if ((new-old) > 0) { 1319313Ssos if (swap_pager_full) 1329313Ssos return ENOMEM; 1339313Ssos error = vm_map_find(&vm->vm_map, NULL, 0, &old, (new-old), FALSE); 1349313Ssos if (error) 1359313Ssos return error; 1369313Ssos vm->vm_dsize += btoc((new-old)); 1379313Ssos *retval = (int)(vm->vm_daddr + ctob(vm->vm_dsize)); 1389313Ssos } 1399313Ssos return 0; 1409313Ssos#else 1419313Ssos struct vmspace *vm = p->p_vmspace; 1429313Ssos vm_offset_t new, old; 1439313Ssos struct obreak_args { 1449313Ssos vm_offset_t newsize; 1459313Ssos } tmp; 1469313Ssos 1479313Ssos#ifdef DEBUG 1489313Ssos printf("Linux-emul(%d): brk(%08x)\n", p->p_pid, args->dsend); 1499313Ssos#endif 1509313Ssos old = (vm_offset_t)vm->vm_daddr + ctob(vm->vm_dsize); 1519313Ssos new = (vm_offset_t)args->dsend; 1529313Ssos tmp.newsize = new; 1539313Ssos if (((caddr_t)new > vm->vm_daddr) && !obreak(p, &tmp, retval)) 1549313Ssos retval[0] = (int)new; 1559313Ssos else 1569313Ssos retval[0] = (int)old; 1579313Ssos 1589313Ssos return 0; 1599313Ssos#endif 1609313Ssos} 1619313Ssos 1629313Ssosstruct linux_uselib_args { 1639313Ssos char *library; 1649313Ssos}; 1659313Ssos 1669313Ssosint 1679313Ssoslinux_uselib(struct proc *p, struct linux_uselib_args *args, int *retval) 1689313Ssos{ 1699313Ssos struct nameidata ni; 17012130Sdg struct vnode *vp; 1719313Ssos struct exec *a_out = 0; 1729313Ssos struct vattr attr; 1739313Ssos unsigned long vmaddr, virtual_offset, file_offset; 1749313Ssos unsigned long buffer, bss_size; 1759313Ssos char *ptr; 1769313Ssos char path[MAXPATHLEN]; 1779313Ssos const char *prefix = "/compat/linux"; 1789313Ssos size_t sz, len; 1799313Ssos int error; 1809313Ssos 1819313Ssos#ifdef DEBUG 1829313Ssos printf("Linux-emul(%d): uselib(%s)\n", p->p_pid, args->library); 1839313Ssos#endif 1849313Ssos 1859313Ssos for (ptr = path; (*ptr = *prefix) != '\0'; ptr++, prefix++) ; 1869313Ssos sz = MAXPATHLEN - (ptr - path); 1879313Ssos if (error = copyinstr(args->library, ptr, sz, &len)) 1889313Ssos return error; 1899313Ssos if (*ptr != '/') 1909313Ssos return EINVAL; 1919313Ssos 1929313Ssos#ifdef DEBUG 1939313Ssos printf("Linux-emul(%d): uselib(%s)\n", p->p_pid, path); 1949313Ssos#endif 1959313Ssos 19611163Sjulian NDINIT(&ni, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, p); 1979313Ssos if (error = namei(&ni)) 1989313Ssos return error; 1999313Ssos 20012130Sdg vp = ni.ni_vp; 20112130Sdg if (vp == NULL) 2029313Ssos return ENOEXEC; 2039313Ssos 20412130Sdg if (vp->v_writecount) { 20512130Sdg VOP_UNLOCK(vp); 2069313Ssos return ETXTBSY; 20711163Sjulian } 2089313Ssos 20912130Sdg if (error = VOP_GETATTR(vp, &attr, p->p_ucred, p)) { 21012130Sdg VOP_UNLOCK(vp); 21111163Sjulian return error; 21211163Sjulian } 2139313Ssos 21412130Sdg if ((vp->v_mount->mnt_flag & MNT_NOEXEC) 2159313Ssos || ((attr.va_mode & 0111) == 0) 21611163Sjulian || (attr.va_type != VREG)) { 21712130Sdg VOP_UNLOCK(vp); 2189313Ssos return ENOEXEC; 21911163Sjulian } 2209313Ssos 22111163Sjulian if (attr.va_size == 0) { 22212130Sdg VOP_UNLOCK(vp); 2239313Ssos return ENOEXEC; 22411163Sjulian } 2259313Ssos 22612130Sdg if (error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p)) { 22712130Sdg VOP_UNLOCK(vp); 2289313Ssos return error; 22911163Sjulian } 2309313Ssos 23112130Sdg if (error = VOP_OPEN(vp, FREAD, p->p_ucred, p)) { 23212130Sdg VOP_UNLOCK(vp); 2339313Ssos return error; 23411163Sjulian } 2359313Ssos 23612130Sdg VOP_UNLOCK(vp); /* lock no longer needed */ 23711163Sjulian 2389313Ssos error = vm_mmap(kernel_map, (vm_offset_t *)&a_out, 1024, 23912130Sdg VM_PROT_READ, VM_PROT_READ, 0, (caddr_t)vp, 0); 2409313Ssos if (error) 2419313Ssos return (error); 2429313Ssos 2439313Ssos /* 2449313Ssos * Is it a Linux binary ? 2459313Ssos */ 2469313Ssos if (((a_out->a_magic >> 16) & 0xff) != 0x64) 24711163Sjulian return ENOEXEC; 2489313Ssos 2499313Ssos /* 2509313Ssos * Set file/virtual offset based on a.out variant. 2519313Ssos */ 2529313Ssos switch ((int)(a_out->a_magic & 0xffff)) { 2539313Ssos case 0413: /* ZMAGIC */ 2549313Ssos virtual_offset = 0; 2559313Ssos file_offset = 1024; 2569313Ssos break; 2579313Ssos case 0314: /* QMAGIC */ 2589313Ssos virtual_offset = 4096; 2599313Ssos file_offset = 0; 2609313Ssos break; 2619313Ssos default: 26211163Sjulian return ENOEXEC; 2639313Ssos } 2649313Ssos 26512130Sdg vp->v_flag |= VTEXT; 2669313Ssos bss_size = round_page(a_out->a_bss); 2679313Ssos /* 2689313Ssos * Check if file_offset page aligned,. 2699313Ssos * Currently we cannot handle misalinged file offsets, 2709313Ssos * and so we read in the entire image (what a waste). 2719313Ssos */ 2729313Ssos if (file_offset & PGOFSET) { 2739313Ssos#ifdef DEBUG 2749313Ssosprintf("uselib: Non page aligned binary %d\n", file_offset); 2759313Ssos#endif 2769313Ssos /* 2779313Ssos * Map text+data read/write/execute 2789313Ssos */ 2799313Ssos vmaddr = virtual_offset + round_page(a_out->a_entry); 2809313Ssos error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr, 2819313Ssos round_page(a_out->a_text + a_out->a_data), FALSE); 2829313Ssos if (error) 2839313Ssos return error; 2849313Ssos 2859313Ssos error = vm_mmap(kernel_map, &buffer, 2869313Ssos round_page(a_out->a_text + a_out->a_data + file_offset), 2879313Ssos VM_PROT_READ, VM_PROT_READ, MAP_FILE, 28812130Sdg (caddr_t)vp, trunc_page(file_offset)); 2899313Ssos if (error) 2909313Ssos return error; 2919313Ssos 2929313Ssos error = copyout((caddr_t)(buffer + file_offset), (caddr_t)vmaddr, 2939313Ssos a_out->a_text + a_out->a_data); 2949313Ssos if (error) 2959313Ssos return error; 2969313Ssos 2979313Ssos vm_map_remove(kernel_map, trunc_page(vmaddr), 2989313Ssos round_page(a_out->a_text + a_out->a_data + file_offset)); 2999313Ssos 3009313Ssos error = vm_map_protect(&p->p_vmspace->vm_map, vmaddr, 3019313Ssos round_page(a_out->a_text + a_out->a_data), 3029313Ssos VM_PROT_ALL, TRUE); 3039313Ssos if (error) 3049313Ssos return error; 3059313Ssos } 3069313Ssos else { 3079313Ssos#ifdef DEBUG 3089313Ssosprintf("uselib: Page aligned binary %d\n", file_offset); 3099313Ssos#endif 3109313Ssos vmaddr = virtual_offset + round_page(a_out->a_entry); 3119313Ssos error = vm_mmap(&p->p_vmspace->vm_map, &vmaddr, 3129313Ssos a_out->a_text + a_out->a_data, 3139313Ssos VM_PROT_ALL, VM_PROT_ALL, MAP_PRIVATE | MAP_FIXED, 31412130Sdg (caddr_t)vp, file_offset); 3159313Ssos if (error) 3169313Ssos return (error); 3179313Ssos } 3189313Ssos#ifdef DEBUG 3199313Ssosprintf("mem=%08x = %08x %08x\n", vmaddr, ((int*)vmaddr)[0], ((int*)vmaddr)[1]); 3209313Ssos#endif 3219313Ssos if (bss_size != 0) { 3229313Ssos vmaddr = virtual_offset + round_page(a_out->a_entry) + 3239313Ssos round_page(a_out->a_text + a_out->a_data); 3249313Ssos error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &vmaddr, 3259313Ssos bss_size, FALSE); 3269313Ssos if (error) 3279313Ssos return error; 3289313Ssos error = vm_map_protect(&p->p_vmspace->vm_map, vmaddr, bss_size, 3299313Ssos VM_PROT_ALL, TRUE); 3309313Ssos if (error) 3319313Ssos return error; 3329313Ssos } 3339313Ssos return 0; 3349313Ssos} 3359313Ssos 3369313Ssosstruct linux_select_args { 3379313Ssos void *ptr; 3389313Ssos}; 3399313Ssos 3409313Ssosint 3419313Ssoslinux_select(struct proc *p, struct linux_select_args *args, int *retval) 3429313Ssos{ 3439313Ssos struct { 3449313Ssos int nfds; 3459313Ssos fd_set *readfds; 3469313Ssos fd_set *writefds; 3479313Ssos fd_set *exceptfds; 3489313Ssos struct timeval *timeout; 3499313Ssos } linux_args; 3509313Ssos struct { 3519313Ssos unsigned int nd; 3529313Ssos fd_set *in; 3539313Ssos fd_set *ou; 3549313Ssos fd_set *ex; 3559313Ssos struct timeval *tv; 3569313Ssos } bsd_args; 3579313Ssos int error; 3589313Ssos 3599313Ssos if ((error = copyin((caddr_t)args->ptr, (caddr_t)&linux_args, 3609313Ssos sizeof(linux_args)))) 3619313Ssos return error; 3629313Ssos#ifdef DEBUG 3639313Ssos printf("Linux-emul(%d): select(%d, %d, %d, %d, %d)\n", 3649313Ssos p->p_pid, linux_args.nfds, linux_args.readfds, 3659313Ssos linux_args.writefds, linux_args.exceptfds, 3669313Ssos linux_args.timeout); 3679313Ssos#endif 3689313Ssos bsd_args.nd = linux_args.nfds; 3699313Ssos bsd_args.in = linux_args.readfds; 3709313Ssos bsd_args.ou = linux_args.writefds; 3719313Ssos bsd_args.ex = linux_args.exceptfds; 3729313Ssos bsd_args.tv = linux_args.timeout; 3739313Ssos return select(p, &bsd_args, retval); 3749313Ssos} 3759313Ssos 3769313Ssosstruct linux_getpgid_args { 3779313Ssos int pid; 3789313Ssos}; 3799313Ssos 3809313Ssosint 3819313Ssoslinux_getpgid(struct proc *p, struct linux_getpgid_args *args, int *retval) 3829313Ssos{ 3839313Ssos struct proc *curproc; 3849313Ssos 3859313Ssos#ifdef DEBUG 3869313Ssos printf("Linux-emul(%d): getpgid(%d)\n", p->p_pid, args->pid); 3879313Ssos#endif 3889313Ssos if (args->pid != p->p_pid) { 3899313Ssos if (!(curproc = pfind(args->pid))) 3909313Ssos return ESRCH; 3919313Ssos } 3929313Ssos else 3939313Ssos curproc = p; 3949313Ssos *retval = curproc->p_pgid; 3959313Ssos return 0; 3969313Ssos} 3979313Ssos 3989313Ssosint 3999313Ssoslinux_fork(struct proc *p, void *args, int *retval) 4009313Ssos{ 4019313Ssos int error; 4029313Ssos 4039313Ssos#ifdef DEBUG 4049313Ssos printf("Linux-emul(%d): fork()\n", p->p_pid); 4059313Ssos#endif 4069313Ssos if (error = fork(p, args, retval)) 4079313Ssos return error; 4089313Ssos if (retval[1] == 1) 4099313Ssos retval[0] = 0; 4109313Ssos return 0; 4119313Ssos} 4129313Ssos 4139313Ssosstruct linux_mmap_args { 4149313Ssos void *ptr; 4159313Ssos}; 4169313Ssos 4179313Ssosint 4189313Ssoslinux_mmap(struct proc *p, struct linux_mmap_args *args, int *retval) 4199313Ssos{ 4209313Ssos struct { 4219313Ssos linux_caddr_t addr; 4229313Ssos int len; 4239313Ssos int prot; 4249313Ssos int flags; 4259313Ssos int fd; 4269313Ssos int pos; 4279313Ssos } linux_args; 4289313Ssos struct { 4299313Ssos caddr_t addr; 4309313Ssos size_t len; 4319313Ssos int prot; 4329313Ssos int flags; 4339313Ssos int fd; 4349313Ssos long pad; 4359313Ssos off_t pos; 4369313Ssos } bsd_args; 4379313Ssos int error; 4389313Ssos 4399313Ssos if ((error = copyin((caddr_t)args->ptr, (caddr_t)&linux_args, 4409313Ssos sizeof(linux_args)))) 4419313Ssos return error; 4429313Ssos#ifdef DEBUG 4439313Ssos printf("Linux-emul(%d): mmap(%08x, %d, %d, %08x, %d, %d)\n", 4449313Ssos p->p_pid, linux_args.addr, linux_args.len, linux_args.prot, 4459313Ssos linux_args.flags, linux_args.fd, linux_args.pos); 4469313Ssos#endif 4479313Ssos bsd_args.flags = 0; 4489313Ssos if (linux_args.flags & LINUX_MAP_SHARED) 4499313Ssos bsd_args.flags |= MAP_SHARED; 4509313Ssos if (linux_args.flags & LINUX_MAP_PRIVATE) 4519313Ssos bsd_args.flags |= MAP_PRIVATE; 4529313Ssos if (linux_args.flags & LINUX_MAP_FIXED) 4539313Ssos bsd_args.flags |= MAP_FIXED; 4549313Ssos if (linux_args.flags & LINUX_MAP_ANON) 4559313Ssos bsd_args.flags |= MAP_ANON; 4569313Ssos bsd_args.addr = linux_args.addr; 4579313Ssos bsd_args.len = linux_args.len; 4589313Ssos bsd_args.prot = linux_args.prot; 4599313Ssos bsd_args.fd = linux_args.fd; 4609313Ssos bsd_args.pos = linux_args.pos; 4619313Ssos bsd_args.pad = 0; 4629313Ssos return mmap(p, &bsd_args, retval); 4639313Ssos} 4649313Ssos 4659313Ssosstruct linux_pipe_args { 4669313Ssos int *pipefds; 4679313Ssos}; 4689313Ssos 4699313Ssosint 4709313Ssoslinux_pipe(struct proc *p, struct linux_pipe_args *args, int *retval) 4719313Ssos{ 4729313Ssos int error; 4739313Ssos 4749313Ssos#ifdef DEBUG 4759313Ssos printf("Linux-emul(%d): pipe(*)\n", p->p_pid); 4769313Ssos#endif 4779313Ssos if (error = pipe(p, 0, retval)) 4789313Ssos return error; 4799313Ssos if (error = copyout(retval, args->pipefds, 2*sizeof(int))) 4809313Ssos return error; 4819313Ssos *retval = 0; 4829313Ssos return 0; 4839313Ssos} 4849313Ssos 4859313Ssosstruct linux_time_args { 4869313Ssos linux_time_t *tm; 4879313Ssos}; 4889313Ssos 4899313Ssosint 4909313Ssoslinux_time(struct proc *p, struct linux_time_args *args, int *retval) 4919313Ssos{ 4929313Ssos struct timeval tv; 4939313Ssos linux_time_t tm; 4949313Ssos int error; 4959313Ssos 4969313Ssos#ifdef DEBUG 4979313Ssos printf("Linux-emul(%d): time(*)\n", p->p_pid); 4989313Ssos#endif 4999313Ssos microtime(&tv); 5009313Ssos tm = tv.tv_sec; 5019313Ssos if (error = copyout(&tm, args->tm, sizeof(linux_time_t))) 5029313Ssos return error; 5039313Ssos *retval = tv.tv_sec; 5049313Ssos return 0; 5059313Ssos} 5069313Ssos 5079313Ssosstruct linux_tms { 5089313Ssos long tms_utime; 5099313Ssos long tms_stime; 5109313Ssos long tms_cutime; 5119313Ssos long tms_cstime; 5129313Ssos}; 5139313Ssos 5149313Ssosstruct linux_tms_args { 5159313Ssos char *buf; 5169313Ssos}; 5179313Ssos 5189313Ssosint 5199313Ssoslinux_times(struct proc *p, struct linux_tms_args *args, int *retval) 5209313Ssos{ 5219313Ssos struct timeval tv; 5229313Ssos struct linux_tms tms; 5239313Ssos 5249313Ssos#ifdef DEBUG 5259313Ssos printf("Linux-emul(%d): times(*)\n", p->p_pid); 5269313Ssos#endif 5279313Ssos tms.tms_utime = p->p_uticks; 5289313Ssos tms.tms_stime = p->p_sticks; 5299313Ssos tms.tms_cutime = p->p_stats->p_cru.ru_utime.tv_sec * hz + 5309313Ssos ((p->p_stats->p_cru.ru_utime.tv_usec * hz)/1000000); 5319313Ssos tms.tms_cstime = p->p_stats->p_cru.ru_stime.tv_sec * hz + 5329313Ssos ((p->p_stats->p_cru.ru_stime.tv_usec * hz)/1000000); 5339313Ssos microtime(&tv); 5349313Ssos *retval = tv.tv_sec * hz + (tv.tv_usec * hz)/1000000; 5359313Ssos return (copyout((caddr_t)&tms, (caddr_t)args->buf, 5369313Ssos sizeof(struct linux_tms))); 5379313Ssos} 5389313Ssos 5399313Ssosstruct linux_newuname_t { 5409313Ssos char sysname[65]; 5419313Ssos char nodename[65]; 5429313Ssos char release[65]; 5439313Ssos char version[65]; 5449313Ssos char machine[65]; 5459313Ssos char domainname[65]; 5469313Ssos}; 5479313Ssos 5489313Ssosstruct linux_newuname_args { 5499313Ssos char *buf; 5509313Ssos}; 5519313Ssos 5529313Ssosint 5539313Ssoslinux_newuname(struct proc *p, struct linux_newuname_args *args, int *retval) 5549313Ssos{ 5559313Ssos struct linux_newuname_t linux_newuname; 5569313Ssos 5579313Ssos#ifdef DEBUG 5589313Ssos printf("Linux-emul(%d): newuname(*)\n", p->p_pid); 5599313Ssos#endif 5609313Ssos bzero(&linux_newuname, sizeof(struct linux_newuname_args)); 5619313Ssos strncpy(linux_newuname.sysname, ostype, 64); 5629313Ssos strncpy(linux_newuname.nodename, hostname, 64); 5639313Ssos strncpy(linux_newuname.release, osrelease, 64); 5649313Ssos strncpy(linux_newuname.version, version, 64); 5659313Ssos strncpy(linux_newuname.machine, machine, 64); 5669313Ssos strncpy(linux_newuname.domainname, domainname, 64); 5679313Ssos return (copyout((caddr_t)&linux_newuname, (caddr_t)args->buf, 5689313Ssos sizeof(struct linux_newuname_t))); 5699313Ssos} 5709313Ssos 5719313Ssosstruct linux_utime_args { 5729313Ssos char *fname; 5739313Ssos linux_time_t *timeptr; 5749313Ssos}; 5759313Ssos 5769313Ssosint 5779313Ssoslinux_utime(struct proc *p, struct linux_utime_args *args, int *retval) 5789313Ssos{ 5799313Ssos struct bsd_utimes_args { 5809313Ssos char *fname; 5819313Ssos struct timeval *tptr; 5829313Ssos } bsdutimes; 5839313Ssos struct timeval tv; 5849313Ssos 5859313Ssos#ifdef DEBUG 5869313Ssos printf("Linux-emul(%d): utime(%s, *)\n", p->p_pid, args->fname); 5879313Ssos#endif 5889313Ssos tv.tv_sec = (long)args->timeptr; 5899313Ssos tv.tv_usec = 0; 5909313Ssos bsdutimes.tptr = &tv; 5919313Ssos bsdutimes.fname = args->fname; 5929313Ssos return utimes(p, &bsdutimes, retval); 5939313Ssos} 5949313Ssos 5959313Ssosstruct linux_waitpid_args { 5969313Ssos int pid; 5979313Ssos int *status; 5989313Ssos int options; 5999313Ssos}; 6009313Ssos 6019313Ssosint 6029313Ssoslinux_waitpid(struct proc *p, struct linux_waitpid_args *args, int *retval) 6039313Ssos{ 6049313Ssos struct wait4_args { 6059313Ssos int pid; 6069313Ssos int *status; 6079313Ssos int options; 6089313Ssos struct rusage *rusage; 6099313Ssos int compat; 6109313Ssos } tmp; 6119313Ssos int error, tmpstat; 6129313Ssos 6139313Ssos#ifdef DEBUG 6149313Ssos printf("Linux-emul(%d): waitpid(%d, *, %d)\n", 6159313Ssos p->p_pid, args->pid, args->options); 6169313Ssos#endif 6179313Ssos tmp.pid = args->pid; 6189313Ssos tmp.status = args->status; 6199313Ssos tmp.options = args->options; 6209313Ssos tmp.rusage = NULL; 6219313Ssos tmp.compat = 0; 6229313Ssos 6239313Ssos if (error = wait4(p, &tmp, retval)) 6249313Ssos return error; 6259313Ssos if (error = copyin(args->status, &tmpstat, sizeof(int))) 6269313Ssos return error; 6279313Ssos if (WIFSIGNALED(tmpstat)) 6289313Ssos tmpstat = (tmpstat & 0xffffff80) | 6299313Ssos bsd_to_linux_signal[WTERMSIG(tmpstat)]; 6309313Ssos else if (WIFSTOPPED(tmpstat)) 6319313Ssos tmpstat = (tmpstat & 0xffff00ff) | 6329313Ssos (bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8); 6339313Ssos return copyout(&tmpstat, args->status, sizeof(int)); 6349313Ssos} 6359313Ssos 6369313Ssosstruct linux_wait4_args { 6379313Ssos int pid; 6389313Ssos int *status; 6399313Ssos int options; 6409313Ssos struct rusage *rusage; 6419313Ssos}; 6429313Ssos 6439313Ssosint 6449313Ssoslinux_wait4(struct proc *p, struct linux_wait4_args *args, int *retval) 6459313Ssos{ 6469313Ssos struct wait4_args { 6479313Ssos int pid; 6489313Ssos int *status; 6499313Ssos int options; 6509313Ssos struct rusage *rusage; 6519313Ssos int compat; 6529313Ssos } tmp; 6539313Ssos int error, tmpstat; 6549313Ssos 6559313Ssos#ifdef DEBUG 6569313Ssos printf("Linux-emul(%d): wait4(%d, *, %d, *)\n", 6579313Ssos p->p_pid, args->pid, args->options); 6589313Ssos#endif 6599313Ssos tmp.pid = args->pid; 6609313Ssos tmp.status = args->status; 6619313Ssos tmp.options = args->options; 6629313Ssos tmp.rusage = args->rusage; 6639313Ssos tmp.compat = 0; 6649313Ssos 6659313Ssos if (error = wait4(p, &tmp, retval)) 6669313Ssos return error; 6679313Ssos if (error = copyin(args->status, &tmpstat, sizeof(int))) 6689313Ssos return error; 6699313Ssos if (WIFSIGNALED(tmpstat)) 6709313Ssos tmpstat = (tmpstat & 0xffffff80) | 6719313Ssos bsd_to_linux_signal[WTERMSIG(tmpstat)]; 6729313Ssos else if (WIFSTOPPED(tmpstat)) 6739313Ssos tmpstat = (tmpstat & 0xffff00ff) | 6749313Ssos (bsd_to_linux_signal[WSTOPSIG(tmpstat)]<<8); 6759313Ssos return copyout(&tmpstat, args->status, sizeof(int)); 6769313Ssos} 677