1139743Simp/*- 243412Snewton * Copyright (c) 1998 Mark Newton 343412Snewton * Copyright (c) 1994 Christos Zoulas 443412Snewton * All rights reserved. 543412Snewton * 643412Snewton * Redistribution and use in source and binary forms, with or without 743412Snewton * modification, are permitted provided that the following conditions 843412Snewton * are met: 943412Snewton * 1. Redistributions of source code must retain the above copyright 1043412Snewton * notice, this list of conditions and the following disclaimer. 1143412Snewton * 2. Redistributions in binary form must reproduce the above copyright 1243412Snewton * notice, this list of conditions and the following disclaimer in the 1343412Snewton * documentation and/or other materials provided with the distribution. 1443412Snewton * 3. The name of the author may not be used to endorse or promote products 1543412Snewton * derived from this software without specific prior written permission 1643412Snewton * 1743412Snewton * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1843412Snewton * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1943412Snewton * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2043412Snewton * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2143412Snewton * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2243412Snewton * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2343412Snewton * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2443412Snewton * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2543412Snewton * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2643412Snewton * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2743412Snewton */ 2843412Snewton/* 2943412Snewton * SVR4 compatibility module. 3043412Snewton * 3143412Snewton * SVR4 system calls that are implemented differently in BSD are 3243412Snewton * handled here. 3343412Snewton */ 3443412Snewton 35116174Sobrien#include <sys/cdefs.h> 36116174Sobrien__FBSDID("$FreeBSD$"); 37116174Sobrien 3843412Snewton#include <sys/param.h> 3943412Snewton#include <sys/systm.h> 40224778Srwatson#include <sys/capability.h> 4143412Snewton#include <sys/dirent.h> 4276166Smarkm#include <sys/fcntl.h> 4343412Snewton#include <sys/filedesc.h> 44141486Sjhb#include <sys/imgact.h> 4543412Snewton#include <sys/kernel.h> 4676166Smarkm#include <sys/lock.h> 4776166Smarkm#include <sys/malloc.h> 4876166Smarkm#include <sys/file.h> /* Must come after sys/malloc.h */ 4943412Snewton#include <sys/mman.h> 5043412Snewton#include <sys/mount.h> 5176166Smarkm#include <sys/msg.h> 5276166Smarkm#include <sys/mutex.h> 5376166Smarkm#include <sys/namei.h> 54164033Srwatson#include <sys/priv.h> 5576166Smarkm#include <sys/proc.h> 5676166Smarkm#include <sys/ptrace.h> 5743412Snewton#include <sys/resource.h> 5843412Snewton#include <sys/resourcevar.h> 5976166Smarkm#include <sys/sem.h> 60138129Sdas#include <sys/signalvar.h> 6176166Smarkm#include <sys/stat.h> 6274940Sjhb#include <sys/sx.h> 63139739Sjhb#include <sys/syscallsubr.h> 6476166Smarkm#include <sys/sysproto.h> 6576166Smarkm#include <sys/time.h> 6676166Smarkm#include <sys/times.h> 6743412Snewton#include <sys/uio.h> 6876166Smarkm#include <sys/vnode.h> 6943412Snewton#include <sys/wait.h> 7043412Snewton 7165302Sobrien#include <compat/svr4/svr4.h> 7265302Sobrien#include <compat/svr4/svr4_types.h> 7365302Sobrien#include <compat/svr4/svr4_signal.h> 7465302Sobrien#include <compat/svr4/svr4_proto.h> 7565302Sobrien#include <compat/svr4/svr4_util.h> 7665302Sobrien#include <compat/svr4/svr4_sysconfig.h> 7765302Sobrien#include <compat/svr4/svr4_dirent.h> 7865302Sobrien#include <compat/svr4/svr4_acl.h> 7965302Sobrien#include <compat/svr4/svr4_ulimit.h> 8065302Sobrien#include <compat/svr4/svr4_statvfs.h> 8165302Sobrien#include <compat/svr4/svr4_hrt.h> 8265302Sobrien#include <compat/svr4/svr4_mman.h> 8365302Sobrien#include <compat/svr4/svr4_wait.h> 8443412Snewton 85163606Srwatson#include <security/mac/mac_framework.h> 86163606Srwatson 8743412Snewton#include <machine/vmparam.h> 8843412Snewton#include <vm/vm.h> 8943412Snewton#include <vm/vm_param.h> 9043412Snewton#include <vm/vm_map.h> 9171452Sjhb#if defined(__FreeBSD__) 9292787Sjeff#include <vm/uma.h> 93109254Sdillon#include <vm/vm_extern.h> 9471452Sjhb#endif 9543412Snewton 9643412Snewton#if defined(NetBSD) 9743412Snewton# if defined(UVM) 9843412Snewton# include <uvm/uvm_extern.h> 9943412Snewton# endif 10043412Snewton#endif 10143412Snewton 10243412Snewton#define BSD_DIRENT(cp) ((struct dirent *)(cp)) 10343412Snewton 10492761Salfredstatic int svr4_mknod(struct thread *, register_t *, char *, 10592761Salfred svr4_mode_t, svr4_dev_t); 10643412Snewton 10792761Salfredstatic __inline clock_t timeval_to_clock_t(struct timeval *); 108160510Sjhbstatic int svr4_setinfo (pid_t , struct rusage *, int, svr4_siginfo_t *); 10943412Snewton 11043412Snewtonstruct svr4_hrtcntl_args; 11192761Salfredstatic int svr4_hrtcntl (struct thread *, struct svr4_hrtcntl_args *, 11292761Salfred register_t *); 11392761Salfredstatic void bsd_statfs_to_svr4_statvfs(const struct statfs *, 11492761Salfred struct svr4_statvfs *); 11592761Salfredstatic void bsd_statfs_to_svr4_statvfs64(const struct statfs *, 11692761Salfred struct svr4_statvfs64 *); 11792761Salfredstatic struct proc *svr4_pfind(pid_t pid); 11843412Snewton 11943412Snewton/* BOGUS noop */ 12043412Snewton#if defined(BOGUS) 12143412Snewtonint 12283366Sjuliansvr4_sys_setitimer(td, uap) 123193014Sdelphij struct thread *td; 12443412Snewton struct svr4_sys_setitimer_args *uap; 12543412Snewton{ 12683366Sjulian td->td_retval[0] = 0; 12743412Snewton return 0; 12843412Snewton} 12943412Snewton#endif 13043412Snewton 13143412Snewtonint 13283366Sjuliansvr4_sys_wait(td, uap) 13383366Sjulian struct thread *td; 13443412Snewton struct svr4_sys_wait_args *uap; 13543412Snewton{ 136127140Sjhb int error, st, sig; 13743412Snewton 138127140Sjhb error = kern_wait(td, WAIT_ANY, &st, 0, NULL); 139127140Sjhb if (error) 140127140Sjhb return (error); 14143412Snewton 14243412Snewton if (WIFSIGNALED(st)) { 14343412Snewton sig = WTERMSIG(st); 14443412Snewton if (sig >= 0 && sig < NSIG) 14551793Smarcel st = (st & ~0177) | SVR4_BSD2SVR4_SIG(sig); 14643412Snewton } else if (WIFSTOPPED(st)) { 14743412Snewton sig = WSTOPSIG(st); 14843412Snewton if (sig >= 0 && sig < NSIG) 14951793Smarcel st = (st & ~0xff00) | (SVR4_BSD2SVR4_SIG(sig) << 8); 15043412Snewton } 15143412Snewton 15243412Snewton /* 15343412Snewton * It looks like wait(2) on svr4/solaris/2.4 returns 15443412Snewton * the status in retval[1], and the pid on retval[0]. 15543412Snewton */ 156127140Sjhb td->td_retval[1] = st; 15743412Snewton 158107849Salfred if (uap->status) 159127140Sjhb error = copyout(&st, uap->status, sizeof(st)); 16043412Snewton 161127140Sjhb return (error); 16243412Snewton} 16343412Snewton 16443412Snewtonint 16583366Sjuliansvr4_sys_execv(td, uap) 16683366Sjulian struct thread *td; 16743412Snewton struct svr4_sys_execv_args *uap; 16843412Snewton{ 169141486Sjhb struct image_args eargs; 170141486Sjhb char *path; 171141486Sjhb int error; 17243412Snewton 173141486Sjhb CHECKALTEXIST(td, uap->path, &path); 17443412Snewton 175141486Sjhb error = exec_copyin_args(&eargs, path, UIO_SYSSPACE, uap->argp, NULL); 176141486Sjhb free(path, M_TEMP); 177141486Sjhb if (error == 0) 178141486Sjhb error = kern_execve(td, &eargs, NULL); 179141486Sjhb return (error); 18043412Snewton} 18143412Snewton 18243412Snewtonint 18383366Sjuliansvr4_sys_execve(td, uap) 18483366Sjulian struct thread *td; 18543412Snewton struct svr4_sys_execve_args *uap; 18643412Snewton{ 187141486Sjhb struct image_args eargs; 188141486Sjhb char *path; 189141486Sjhb int error; 19043412Snewton 191141486Sjhb CHECKALTEXIST(td, uap->path, &path); 19243412Snewton 193141486Sjhb error = exec_copyin_args(&eargs, path, UIO_SYSSPACE, uap->argp, 194141486Sjhb uap->envp); 195141486Sjhb free(path, M_TEMP); 196141486Sjhb if (error == 0) 197141486Sjhb error = kern_execve(td, &eargs, NULL); 198141486Sjhb return (error); 19943412Snewton} 20043412Snewton 20143412Snewtonint 20283366Sjuliansvr4_sys_time(td, v) 20383366Sjulian struct thread *td; 20443412Snewton struct svr4_sys_time_args *v; 20543412Snewton{ 20643412Snewton struct svr4_sys_time_args *uap = v; 20743412Snewton int error = 0; 20843412Snewton struct timeval tv; 20943412Snewton 21043412Snewton microtime(&tv); 211107849Salfred if (uap->t) 212107849Salfred error = copyout(&tv.tv_sec, uap->t, 213107849Salfred sizeof(*(uap->t))); 21483366Sjulian td->td_retval[0] = (int) tv.tv_sec; 21543412Snewton 21643412Snewton return error; 21743412Snewton} 21843412Snewton 21943412Snewton 22043412Snewton/* 22143412Snewton * Read SVR4-style directory entries. We suck them into kernel space so 22254494Snewton * that they can be massaged before being copied out to user code. 22343412Snewton * 22454494Snewton * This code is ported from the Linux emulator: Changes to the VFS interface 22554494Snewton * between FreeBSD and NetBSD have made it simpler to port it from there than 22654494Snewton * to adapt the NetBSD version. 22743412Snewton */ 22843412Snewtonint 22983366Sjuliansvr4_sys_getdents64(td, uap) 23083366Sjulian struct thread *td; 23143412Snewton struct svr4_sys_getdents64_args *uap; 23243412Snewton{ 233193014Sdelphij struct dirent *bdp; 23443412Snewton struct vnode *vp; 23554494Snewton caddr_t inp, buf; /* BSD-format */ 23654494Snewton int len, reclen; /* BSD-format */ 23754494Snewton caddr_t outp; /* SVR4-format */ 23854494Snewton int resid, svr4reclen=0; /* SVR4-format */ 23943412Snewton struct file *fp; 24043412Snewton struct uio auio; 24143412Snewton struct iovec aiov; 24254494Snewton off_t off; 24354494Snewton struct svr4_dirent64 svr4_dirent; 244160276Sjhb int buflen, error, eofflag, nbytes, justone, vfslocked; 24554494Snewton u_long *cookies = NULL, *cookiep; 24654494Snewton int ncookies; 24743412Snewton 24854494Snewton DPRINTF(("svr4_sys_getdents64(%d, *, %d)\n", 249107849Salfred uap->fd, uap->nbytes)); 250224778Srwatson if ((error = getvnode(td->td_proc->p_fd, uap->fd, 251224778Srwatson CAP_READ | CAP_SEEK, &fp)) != 0) { 25243412Snewton return (error); 25354494Snewton } 25443412Snewton 25589306Salfred if ((fp->f_flag & FREAD) == 0) { 25689306Salfred fdrop(fp, td); 25743412Snewton return (EBADF); 25889306Salfred } 25943412Snewton 260116678Sphk vp = fp->f_vnode; 261160276Sjhb vfslocked = VFS_LOCK_GIANT(vp->v_mount); 26289306Salfred if (vp->v_type != VDIR) { 263160276Sjhb VFS_UNLOCK_GIANT(vfslocked); 26489306Salfred fdrop(fp, td); 26543412Snewton return (EINVAL); 26689306Salfred } 26743412Snewton 268107849Salfred nbytes = uap->nbytes; 26954494Snewton if (nbytes == 1) { 27054494Snewton nbytes = sizeof (struct svr4_dirent64); 27154494Snewton justone = 1; 27254494Snewton } 27354494Snewton else 27454494Snewton justone = 0; 27554494Snewton 27654494Snewton off = fp->f_offset; 27754494Snewton#define DIRBLKSIZ 512 /* XXX we used to use ufs's DIRBLKSIZ */ 27854494Snewton buflen = max(DIRBLKSIZ, nbytes); 27954494Snewton buflen = min(buflen, MAXBSIZE); 280111119Simp buf = malloc(buflen, M_TEMP, M_WAITOK); 281188588Sjhb vn_lock(vp, LK_SHARED | LK_RETRY); 28243412Snewtonagain: 28343412Snewton aiov.iov_base = buf; 28443412Snewton aiov.iov_len = buflen; 28543412Snewton auio.uio_iov = &aiov; 28643412Snewton auio.uio_iovcnt = 1; 28743412Snewton auio.uio_rw = UIO_READ; 28843412Snewton auio.uio_segflg = UIO_SYSSPACE; 28983366Sjulian auio.uio_td = td; 29043412Snewton auio.uio_resid = buflen; 29143412Snewton auio.uio_offset = off; 29243412Snewton 29354494Snewton if (cookies) { 29454494Snewton free(cookies, M_TEMP); 29554494Snewton cookies = NULL; 29654494Snewton } 29754494Snewton 298101709Srwatson#ifdef MAC 299172930Srwatson error = mac_vnode_check_readdir(td->td_ucred, vp); 300101709Srwatson if (error) 301101924Srwatson goto out; 302101709Srwatson#endif 303101709Srwatson 30454494Snewton error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, 30554494Snewton &ncookies, &cookies); 30654494Snewton if (error) { 30743412Snewton goto out; 30854494Snewton } 30943412Snewton 31043412Snewton inp = buf; 311107849Salfred outp = (caddr_t) uap->dp; 31254494Snewton resid = nbytes; 31354494Snewton if ((len = buflen - auio.uio_resid) <= 0) { 31443412Snewton goto eof; 31554494Snewton } 31643412Snewton 31754494Snewton cookiep = cookies; 31854494Snewton 31954494Snewton if (cookies) { 32054494Snewton /* 32154494Snewton * When using cookies, the vfs has the option of reading from 32254494Snewton * a different offset than that supplied (UFS truncates the 32354494Snewton * offset to a block boundary to make sure that it never reads 32454494Snewton * partway through a directory entry, even if the directory 32554494Snewton * has been compacted). 32654494Snewton */ 32754494Snewton while (len > 0 && ncookies > 0 && *cookiep <= off) { 32854494Snewton bdp = (struct dirent *) inp; 32954494Snewton len -= bdp->d_reclen; 33054494Snewton inp += bdp->d_reclen; 33154494Snewton cookiep++; 33254494Snewton ncookies--; 33354494Snewton } 33454494Snewton } 33554494Snewton 33654494Snewton while (len > 0) { 33754494Snewton if (cookiep && ncookies == 0) 33854494Snewton break; 33954494Snewton bdp = (struct dirent *) inp; 34043412Snewton reclen = bdp->d_reclen; 34154494Snewton if (reclen & 3) { 34254494Snewton DPRINTF(("svr4_readdir: reclen=%d\n", reclen)); 34354494Snewton error = EFAULT; 34454494Snewton goto out; 34554494Snewton } 34654494Snewton 34743412Snewton if (bdp->d_fileno == 0) { 34854494Snewton inp += reclen; 34954494Snewton if (cookiep) { 35054494Snewton off = *cookiep++; 35154494Snewton ncookies--; 35254494Snewton } else 35354494Snewton off += reclen; 35454494Snewton len -= reclen; 35543412Snewton continue; 35643412Snewton } 35754494Snewton svr4reclen = SVR4_RECLEN(&svr4_dirent, bdp->d_namlen); 35854494Snewton if (reclen > len || resid < svr4reclen) { 35943412Snewton outp++; 36043412Snewton break; 36143412Snewton } 36254494Snewton svr4_dirent.d_ino = (long) bdp->d_fileno; 36354494Snewton if (justone) { 36454494Snewton /* 36554494Snewton * old svr4-style readdir usage. 36654494Snewton */ 36754494Snewton svr4_dirent.d_off = (svr4_off_t) svr4reclen; 36854494Snewton svr4_dirent.d_reclen = (u_short) bdp->d_namlen; 36954494Snewton } else { 37054494Snewton svr4_dirent.d_off = (svr4_off_t)(off + reclen); 37154494Snewton svr4_dirent.d_reclen = (u_short) svr4reclen; 37254494Snewton } 373192994Sdelphij strlcpy(svr4_dirent.d_name, bdp->d_name, sizeof(svr4_dirent.d_name)); 37454494Snewton if ((error = copyout((caddr_t)&svr4_dirent, outp, svr4reclen))) 37543412Snewton goto out; 37643412Snewton inp += reclen; 37754494Snewton if (cookiep) { 37854494Snewton off = *cookiep++; 37954494Snewton ncookies--; 38054494Snewton } else 38154494Snewton off += reclen; 38254494Snewton outp += svr4reclen; 38354494Snewton resid -= svr4reclen; 38454494Snewton len -= reclen; 38554494Snewton if (justone) 38654494Snewton break; 38754494Snewton } 38854494Snewton 389107849Salfred if (outp == (caddr_t) uap->dp) 39043412Snewton goto again; 39154494Snewton fp->f_offset = off; 39243412Snewton 39354494Snewton if (justone) 39454494Snewton nbytes = resid + svr4reclen; 39554494Snewton 39643412Snewtoneof: 39783366Sjulian td->td_retval[0] = nbytes - resid; 39843412Snewtonout: 399175294Sattilio VOP_UNLOCK(vp, 0); 400160276Sjhb VFS_UNLOCK_GIANT(vfslocked); 40189306Salfred fdrop(fp, td); 40254494Snewton if (cookies) 40354494Snewton free(cookies, M_TEMP); 40443412Snewton free(buf, M_TEMP); 40543412Snewton return error; 40643412Snewton} 40743412Snewton 40843412Snewton 40943412Snewtonint 41083366Sjuliansvr4_sys_getdents(td, uap) 41183366Sjulian struct thread *td; 41243412Snewton struct svr4_sys_getdents_args *uap; 41343412Snewton{ 41443412Snewton struct dirent *bdp; 41543412Snewton struct vnode *vp; 41643412Snewton caddr_t inp, buf; /* BSD-format */ 41743412Snewton int len, reclen; /* BSD-format */ 41843412Snewton caddr_t outp; /* SVR4-format */ 41943412Snewton int resid, svr4_reclen; /* SVR4-format */ 42043412Snewton struct file *fp; 42143412Snewton struct uio auio; 42243412Snewton struct iovec aiov; 42343412Snewton struct svr4_dirent idb; 42443412Snewton off_t off; /* true file offset */ 425160276Sjhb int buflen, error, eofflag, vfslocked; 42643412Snewton u_long *cookiebuf = NULL, *cookie; 42783366Sjulian int ncookies = 0, *retval = td->td_retval; 42843412Snewton 429121275Stjr if (uap->nbytes < 0) 430121275Stjr return (EINVAL); 431121275Stjr 432224778Srwatson if ((error = getvnode(td->td_proc->p_fd, uap->fd, 433224778Srwatson CAP_READ | CAP_SEEK, &fp)) != 0) 43443412Snewton return (error); 43543412Snewton 43689306Salfred if ((fp->f_flag & FREAD) == 0) { 43789306Salfred fdrop(fp, td); 43843412Snewton return (EBADF); 43989306Salfred } 44043412Snewton 441116678Sphk vp = fp->f_vnode; 442160276Sjhb vfslocked = VFS_LOCK_GIANT(vp->v_mount); 44389306Salfred if (vp->v_type != VDIR) { 444160276Sjhb VFS_UNLOCK_GIANT(vfslocked); 44589306Salfred fdrop(fp, td); 44643412Snewton return (EINVAL); 44789306Salfred } 44843412Snewton 449107849Salfred buflen = min(MAXBSIZE, uap->nbytes); 450111119Simp buf = malloc(buflen, M_TEMP, M_WAITOK); 451188588Sjhb vn_lock(vp, LK_SHARED | LK_RETRY); 45243412Snewton off = fp->f_offset; 45343412Snewtonagain: 45443412Snewton aiov.iov_base = buf; 45543412Snewton aiov.iov_len = buflen; 45643412Snewton auio.uio_iov = &aiov; 45743412Snewton auio.uio_iovcnt = 1; 45843412Snewton auio.uio_rw = UIO_READ; 45943412Snewton auio.uio_segflg = UIO_SYSSPACE; 46083366Sjulian auio.uio_td = td; 46143412Snewton auio.uio_resid = buflen; 46243412Snewton auio.uio_offset = off; 463101709Srwatson 464101709Srwatson#ifdef MAC 465172930Srwatson error = mac_vnode_check_readdir(td->td_ucred, vp); 466101709Srwatson if (error) 467101709Srwatson goto out; 468101709Srwatson#endif 469101709Srwatson 47043412Snewton /* 47143412Snewton * First we read into the malloc'ed buffer, then 47243412Snewton * we massage it into user space, one record at a time. 47343412Snewton */ 47443412Snewton error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies, 47543412Snewton &cookiebuf); 47689306Salfred if (error) { 47743412Snewton goto out; 47889306Salfred } 47943412Snewton 48043412Snewton inp = buf; 481107849Salfred outp = uap->buf; 482107849Salfred resid = uap->nbytes; 48343412Snewton if ((len = buflen - auio.uio_resid) == 0) 48443412Snewton goto eof; 48543412Snewton 48643412Snewton for (cookie = cookiebuf; len > 0; len -= reclen) { 48743412Snewton bdp = (struct dirent *)inp; 48843412Snewton reclen = bdp->d_reclen; 48943412Snewton if (reclen & 3) 49054494Snewton panic("svr4_sys_getdents64: bad reclen"); 491193013Sdelphij if (cookie) 492193013Sdelphij off = *cookie++; /* each entry points to the next */ 493193013Sdelphij else 494193013Sdelphij off += reclen; 49543412Snewton if ((off >> 32) != 0) { 49654494Snewton uprintf("svr4_sys_getdents64: dir offset too large for emulated program"); 49743412Snewton error = EINVAL; 49843412Snewton goto out; 49943412Snewton } 50043412Snewton if (bdp->d_fileno == 0) { 50143412Snewton inp += reclen; /* it is a hole; squish it out */ 50243412Snewton continue; 50343412Snewton } 50443412Snewton svr4_reclen = SVR4_RECLEN(&idb, bdp->d_namlen); 50543412Snewton if (reclen > len || resid < svr4_reclen) { 50643412Snewton /* entry too big for buffer, so just stop */ 50743412Snewton outp++; 50843412Snewton break; 50943412Snewton } 51043412Snewton /* 51143412Snewton * Massage in place to make a SVR4-shaped dirent (otherwise 51243412Snewton * we have to worry about touching user memory outside of 51343412Snewton * the copyout() call). 51443412Snewton */ 51543412Snewton idb.d_ino = (svr4_ino_t)bdp->d_fileno; 51643412Snewton idb.d_off = (svr4_off_t)off; 51743412Snewton idb.d_reclen = (u_short)svr4_reclen; 518192994Sdelphij strlcpy(idb.d_name, bdp->d_name, sizeof(idb.d_name)); 51943412Snewton if ((error = copyout((caddr_t)&idb, outp, svr4_reclen))) 52043412Snewton goto out; 52143412Snewton /* advance past this real entry */ 52243412Snewton inp += reclen; 52343412Snewton /* advance output past SVR4-shaped entry */ 52443412Snewton outp += svr4_reclen; 52543412Snewton resid -= svr4_reclen; 52643412Snewton } 52743412Snewton 52843412Snewton /* if we squished out the whole block, try again */ 529107849Salfred if (outp == uap->buf) 53043412Snewton goto again; 53143412Snewton fp->f_offset = off; /* update the vnode offset */ 53243412Snewton 53343412Snewtoneof: 534107849Salfred *retval = uap->nbytes - resid; 53543412Snewtonout: 536175294Sattilio VOP_UNLOCK(vp, 0); 537160276Sjhb VFS_UNLOCK_GIANT(vfslocked); 53889306Salfred fdrop(fp, td); 53943412Snewton if (cookiebuf) 54043412Snewton free(cookiebuf, M_TEMP); 54143412Snewton free(buf, M_TEMP); 54243412Snewton return error; 54343412Snewton} 54443412Snewton 54543412Snewton 54643412Snewtonint 54783366Sjuliansvr4_sys_mmap(td, uap) 54883366Sjulian struct thread *td; 54943412Snewton struct svr4_sys_mmap_args *uap; 55043412Snewton{ 55143412Snewton struct mmap_args mm; 55243412Snewton int *retval; 55343412Snewton 55483366Sjulian retval = td->td_retval; 55543412Snewton#define _MAP_NEW 0x80000000 55643412Snewton /* 55743412Snewton * Verify the arguments. 55843412Snewton */ 559107849Salfred if (uap->prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) 56043412Snewton return EINVAL; /* XXX still needed? */ 56143412Snewton 562107849Salfred if (uap->len == 0) 56343412Snewton return EINVAL; 56443412Snewton 565107849Salfred mm.prot = uap->prot; 566107849Salfred mm.len = uap->len; 567107849Salfred mm.flags = uap->flags & ~_MAP_NEW; 568107849Salfred mm.fd = uap->fd; 569107849Salfred mm.addr = uap->addr; 570107849Salfred mm.pos = uap->pos; 57143412Snewton 572225617Skmacy return sys_mmap(td, &mm); 57343412Snewton} 57443412Snewton 57543412Snewtonint 57683366Sjuliansvr4_sys_mmap64(td, uap) 57783366Sjulian struct thread *td; 57843412Snewton struct svr4_sys_mmap64_args *uap; 57943412Snewton{ 58043412Snewton struct mmap_args mm; 58143412Snewton void *rp; 58243412Snewton 58343412Snewton#define _MAP_NEW 0x80000000 58443412Snewton /* 58543412Snewton * Verify the arguments. 58643412Snewton */ 587107849Salfred if (uap->prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) 58843412Snewton return EINVAL; /* XXX still needed? */ 58943412Snewton 590107849Salfred if (uap->len == 0) 59143412Snewton return EINVAL; 59243412Snewton 593107849Salfred mm.prot = uap->prot; 594107849Salfred mm.len = uap->len; 595107849Salfred mm.flags = uap->flags & ~_MAP_NEW; 596107849Salfred mm.fd = uap->fd; 597107849Salfred mm.addr = uap->addr; 598107849Salfred mm.pos = uap->pos; 59943412Snewton 60084783Sps rp = (void *) round_page((vm_offset_t)(td->td_proc->p_vmspace->vm_daddr + maxdsiz)); 601107849Salfred if ((mm.flags & MAP_FIXED) == 0 && 602107849Salfred mm.addr != 0 && (void *)mm.addr < rp) 603107849Salfred mm.addr = rp; 60443412Snewton 605225617Skmacy return sys_mmap(td, &mm); 60643412Snewton} 60743412Snewton 60843412Snewton 60943412Snewtonint 61083366Sjuliansvr4_sys_fchroot(td, uap) 61183366Sjulian struct thread *td; 61243412Snewton struct svr4_sys_fchroot_args *uap; 61343412Snewton{ 61483366Sjulian struct filedesc *fdp = td->td_proc->p_fd; 615160557Sjhb struct vnode *vp; 61643412Snewton struct file *fp; 617160557Sjhb int error, vfslocked; 61843412Snewton 619170587Srwatson if ((error = priv_check(td, PRIV_VFS_FCHROOT)) != 0) 62043412Snewton return error; 621224778Srwatson /* XXX: we have the chroot priv... what cap might we need? all? */ 622224778Srwatson if ((error = getvnode(fdp, uap->fd, 0, &fp)) != 0) 62343412Snewton return error; 624116678Sphk vp = fp->f_vnode; 625160557Sjhb VREF(vp); 626160557Sjhb fdrop(fp, td); 627160557Sjhb vfslocked = VFS_LOCK_GIANT(vp->v_mount); 628175202Sattilio vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 629160557Sjhb error = change_dir(vp, td); 630160557Sjhb if (error) 631160557Sjhb goto fail; 632160557Sjhb#ifdef MAC 633172930Srwatson error = mac_vnode_check_chroot(td->td_ucred, vp); 634160557Sjhb if (error) 635160557Sjhb goto fail; 636160557Sjhb#endif 637175294Sattilio VOP_UNLOCK(vp, 0); 638160557Sjhb error = change_root(vp, td); 639160557Sjhb vrele(vp); 640160557Sjhb VFS_UNLOCK_GIANT(vfslocked); 641160557Sjhb return (error); 642160557Sjhbfail: 643160557Sjhb vput(vp); 644160557Sjhb VFS_UNLOCK_GIANT(vfslocked); 645160557Sjhb return (error); 64643412Snewton} 64743412Snewton 64843412Snewton 64943412Snewtonstatic int 65083366Sjuliansvr4_mknod(td, retval, path, mode, dev) 65183366Sjulian struct thread *td; 65243412Snewton register_t *retval; 65343412Snewton char *path; 65443412Snewton svr4_mode_t mode; 65543412Snewton svr4_dev_t dev; 65643412Snewton{ 657141486Sjhb char *newpath; 658141486Sjhb int error; 65943412Snewton 660141486Sjhb CHECKALTEXIST(td, path, &newpath); 66143412Snewton 662141486Sjhb if (S_ISFIFO(mode)) 663141486Sjhb error = kern_mkfifo(td, newpath, UIO_SYSSPACE, mode); 664141486Sjhb else 665141486Sjhb error = kern_mknod(td, newpath, UIO_SYSSPACE, mode, dev); 666141486Sjhb free(newpath, M_TEMP); 667141486Sjhb return (error); 66843412Snewton} 66943412Snewton 67043412Snewton 67143412Snewtonint 67283366Sjuliansvr4_sys_mknod(td, uap) 673193014Sdelphij struct thread *td; 67443412Snewton struct svr4_sys_mknod_args *uap; 67543412Snewton{ 67683366Sjulian int *retval = td->td_retval; 67783366Sjulian return svr4_mknod(td, retval, 678107849Salfred uap->path, uap->mode, 679107849Salfred (svr4_dev_t)svr4_to_bsd_odev_t(uap->dev)); 68043412Snewton} 68143412Snewton 68243412Snewton 68343412Snewtonint 68483366Sjuliansvr4_sys_xmknod(td, uap) 68583366Sjulian struct thread *td; 68643412Snewton struct svr4_sys_xmknod_args *uap; 68743412Snewton{ 68883366Sjulian int *retval = td->td_retval; 68983366Sjulian return svr4_mknod(td, retval, 690107849Salfred uap->path, uap->mode, 691107849Salfred (svr4_dev_t)svr4_to_bsd_dev_t(uap->dev)); 69243412Snewton} 69343412Snewton 69443412Snewton 69543412Snewtonint 69683366Sjuliansvr4_sys_vhangup(td, uap) 69783366Sjulian struct thread *td; 69843412Snewton struct svr4_sys_vhangup_args *uap; 69943412Snewton{ 70043412Snewton return 0; 70143412Snewton} 70243412Snewton 70343412Snewton 70443412Snewtonint 70583366Sjuliansvr4_sys_sysconfig(td, uap) 70683366Sjulian struct thread *td; 70743412Snewton struct svr4_sys_sysconfig_args *uap; 70843412Snewton{ 70943412Snewton int *retval; 71043412Snewton 71183366Sjulian retval = &(td->td_retval[0]); 71243412Snewton 713107849Salfred switch (uap->name) { 71443412Snewton case SVR4_CONFIG_NGROUPS: 715202143Sbrooks *retval = ngroups_max; 71643412Snewton break; 71743412Snewton case SVR4_CONFIG_CHILD_MAX: 71843412Snewton *retval = maxproc; 71943412Snewton break; 72043412Snewton case SVR4_CONFIG_OPEN_FILES: 72143412Snewton *retval = maxfiles; 72243412Snewton break; 72343412Snewton case SVR4_CONFIG_POSIX_VER: 72443412Snewton *retval = 198808; 72543412Snewton break; 72643412Snewton case SVR4_CONFIG_PAGESIZE: 72743412Snewton *retval = PAGE_SIZE; 72843412Snewton break; 72943412Snewton case SVR4_CONFIG_CLK_TCK: 73043412Snewton *retval = 60; /* should this be `hz', ie. 100? */ 73143412Snewton break; 73243412Snewton case SVR4_CONFIG_XOPEN_VER: 73343412Snewton *retval = 2; /* XXX: What should that be? */ 73443412Snewton break; 73543412Snewton case SVR4_CONFIG_PROF_TCK: 73643412Snewton *retval = 60; /* XXX: What should that be? */ 73743412Snewton break; 73843412Snewton case SVR4_CONFIG_NPROC_CONF: 73943412Snewton *retval = 1; /* Only one processor for now */ 74043412Snewton break; 74143412Snewton case SVR4_CONFIG_NPROC_ONLN: 74243412Snewton *retval = 1; /* And it better be online */ 74343412Snewton break; 74443412Snewton case SVR4_CONFIG_AIO_LISTIO_MAX: 74543412Snewton case SVR4_CONFIG_AIO_MAX: 74643412Snewton case SVR4_CONFIG_AIO_PRIO_DELTA_MAX: 74743412Snewton *retval = 0; /* No aio support */ 74843412Snewton break; 74943412Snewton case SVR4_CONFIG_DELAYTIMER_MAX: 75043412Snewton *retval = 0; /* No delaytimer support */ 75143412Snewton break; 75243412Snewton case SVR4_CONFIG_MQ_OPEN_MAX: 75343412Snewton *retval = msginfo.msgmni; 75443412Snewton break; 75543412Snewton case SVR4_CONFIG_MQ_PRIO_MAX: 75643412Snewton *retval = 0; /* XXX: Don't know */ 75743412Snewton break; 75843412Snewton case SVR4_CONFIG_RTSIG_MAX: 75943412Snewton *retval = 0; 76043412Snewton break; 76143412Snewton case SVR4_CONFIG_SEM_NSEMS_MAX: 76243412Snewton *retval = seminfo.semmni; 76343412Snewton break; 76443412Snewton case SVR4_CONFIG_SEM_VALUE_MAX: 76543412Snewton *retval = seminfo.semvmx; 76643412Snewton break; 76743412Snewton case SVR4_CONFIG_SIGQUEUE_MAX: 76843412Snewton *retval = 0; /* XXX: Don't know */ 76943412Snewton break; 77043412Snewton case SVR4_CONFIG_SIGRT_MIN: 77143412Snewton case SVR4_CONFIG_SIGRT_MAX: 77243412Snewton *retval = 0; /* No real time signals */ 77343412Snewton break; 77443412Snewton case SVR4_CONFIG_TIMER_MAX: 77543412Snewton *retval = 3; /* XXX: real, virtual, profiling */ 77643412Snewton break; 77743412Snewton#if defined(NOTYET) 77843412Snewton case SVR4_CONFIG_PHYS_PAGES: 77943412Snewton#if defined(UVM) 78043412Snewton *retval = uvmexp.free; /* XXX: free instead of total */ 78143412Snewton#else 782170170Sattilio *retval = cnt.v_free_count; /* XXX: free instead of total */ 78343412Snewton#endif 78443412Snewton break; 78543412Snewton case SVR4_CONFIG_AVPHYS_PAGES: 78643412Snewton#if defined(UVM) 78743412Snewton *retval = uvmexp.active; /* XXX: active instead of avg */ 78843412Snewton#else 789170170Sattilio *retval = cnt.v_active_count; /* XXX: active instead of avg */ 79043412Snewton#endif 79143412Snewton break; 79243412Snewton#endif /* NOTYET */ 793193012Sdelphij case SVR4_CONFIG_COHERENCY: 794193012Sdelphij *retval = 0; /* XXX */ 795193012Sdelphij break; 796193012Sdelphij case SVR4_CONFIG_SPLIT_CACHE: 797193012Sdelphij *retval = 0; /* XXX */ 798193012Sdelphij break; 799193012Sdelphij case SVR4_CONFIG_ICACHESZ: 800193012Sdelphij *retval = 256; /* XXX */ 801193012Sdelphij break; 802193012Sdelphij case SVR4_CONFIG_DCACHESZ: 803193012Sdelphij *retval = 256; /* XXX */ 804193012Sdelphij break; 805193012Sdelphij case SVR4_CONFIG_ICACHELINESZ: 806193012Sdelphij *retval = 64; /* XXX */ 807193012Sdelphij break; 808193012Sdelphij case SVR4_CONFIG_DCACHELINESZ: 809193012Sdelphij *retval = 64; /* XXX */ 810193012Sdelphij break; 811193012Sdelphij case SVR4_CONFIG_ICACHEBLKSZ: 812193012Sdelphij *retval = 64; /* XXX */ 813193012Sdelphij break; 814193012Sdelphij case SVR4_CONFIG_DCACHEBLKSZ: 815193012Sdelphij *retval = 64; /* XXX */ 816193012Sdelphij break; 817193012Sdelphij case SVR4_CONFIG_DCACHETBLKSZ: 818193012Sdelphij *retval = 64; /* XXX */ 819193012Sdelphij break; 820193012Sdelphij case SVR4_CONFIG_ICACHE_ASSOC: 821193012Sdelphij *retval = 1; /* XXX */ 822193012Sdelphij break; 823193012Sdelphij case SVR4_CONFIG_DCACHE_ASSOC: 824193012Sdelphij *retval = 1; /* XXX */ 825193012Sdelphij break; 826193012Sdelphij case SVR4_CONFIG_MAXPID: 827193012Sdelphij *retval = PID_MAX; 828193012Sdelphij break; 829193012Sdelphij case SVR4_CONFIG_STACK_PROT: 830193012Sdelphij *retval = PROT_READ|PROT_WRITE|PROT_EXEC; 831193012Sdelphij break; 83243412Snewton default: 83343412Snewton return EINVAL; 83443412Snewton } 83543412Snewton return 0; 83643412Snewton} 83743412Snewton 83843412Snewton/* ARGSUSED */ 83943412Snewtonint 84083366Sjuliansvr4_sys_break(td, uap) 84183366Sjulian struct thread *td; 84243412Snewton struct svr4_sys_break_args *uap; 84343412Snewton{ 844159960Sjhb struct obreak_args ap; 84543412Snewton 846159960Sjhb ap.nsize = uap->nsize; 847225617Skmacy return (sys_obreak(td, &ap)); 84843412Snewton} 84943412Snewton 85043412Snewtonstatic __inline clock_t 85143412Snewtontimeval_to_clock_t(tv) 85243412Snewton struct timeval *tv; 85343412Snewton{ 85443412Snewton return tv->tv_sec * hz + tv->tv_usec / (1000000 / hz); 85543412Snewton} 85643412Snewton 85743412Snewton 85843412Snewtonint 85983366Sjuliansvr4_sys_times(td, uap) 86083366Sjulian struct thread *td; 86143412Snewton struct svr4_sys_times_args *uap; 86243412Snewton{ 863136152Sjhb struct timeval tv, utime, stime, cutime, cstime; 864136152Sjhb struct tms tms; 865136152Sjhb struct proc *p; 866136152Sjhb int error; 86743412Snewton 868136152Sjhb p = td->td_proc; 869136152Sjhb PROC_LOCK(p); 870170472Sattilio PROC_SLOCK(p); 871136152Sjhb calcru(p, &utime, &stime); 872170472Sattilio PROC_SUNLOCK(p); 873136152Sjhb calccru(p, &cutime, &cstime); 874136152Sjhb PROC_UNLOCK(p); 87543412Snewton 876136152Sjhb tms.tms_utime = timeval_to_clock_t(&utime); 877136152Sjhb tms.tms_stime = timeval_to_clock_t(&stime); 87843412Snewton 879136152Sjhb tms.tms_cutime = timeval_to_clock_t(&cutime); 880136152Sjhb tms.tms_cstime = timeval_to_clock_t(&cstime); 88143412Snewton 882136152Sjhb error = copyout(&tms, uap->tp, sizeof(tms)); 88343412Snewton if (error) 884136152Sjhb return (error); 88543412Snewton 886136152Sjhb microtime(&tv); 887136152Sjhb td->td_retval[0] = (int)timeval_to_clock_t(&tv); 888136152Sjhb return (0); 88943412Snewton} 89043412Snewton 89143412Snewton 89243412Snewtonint 89383366Sjuliansvr4_sys_ulimit(td, uap) 89483366Sjulian struct thread *td; 89543412Snewton struct svr4_sys_ulimit_args *uap; 89643412Snewton{ 89783366Sjulian int *retval = td->td_retval; 898125454Sjhb int error; 89943412Snewton 900107849Salfred switch (uap->cmd) { 90143412Snewton case SVR4_GFILLIM: 902125454Sjhb PROC_LOCK(td->td_proc); 903125454Sjhb *retval = lim_cur(td->td_proc, RLIMIT_FSIZE) / 512; 904125454Sjhb PROC_UNLOCK(td->td_proc); 90543412Snewton if (*retval == -1) 90643412Snewton *retval = 0x7fffffff; 90743412Snewton return 0; 90843412Snewton 90943412Snewton case SVR4_SFILLIM: 91043412Snewton { 91143412Snewton struct rlimit krl; 91243412Snewton 913107849Salfred krl.rlim_cur = uap->newlimit * 512; 914125454Sjhb PROC_LOCK(td->td_proc); 915125454Sjhb krl.rlim_max = lim_max(td->td_proc, RLIMIT_FSIZE); 916125454Sjhb PROC_UNLOCK(td->td_proc); 91743412Snewton 918125454Sjhb error = kern_setrlimit(td, RLIMIT_FSIZE, &krl); 91943412Snewton if (error) 92043412Snewton return error; 92143412Snewton 922125454Sjhb PROC_LOCK(td->td_proc); 923125454Sjhb *retval = lim_cur(td->td_proc, RLIMIT_FSIZE); 924125454Sjhb PROC_UNLOCK(td->td_proc); 92543412Snewton if (*retval == -1) 92643412Snewton *retval = 0x7fffffff; 92743412Snewton return 0; 92843412Snewton } 92943412Snewton 93043412Snewton case SVR4_GMEMLIM: 93143412Snewton { 93283366Sjulian struct vmspace *vm = td->td_proc->p_vmspace; 93371452Sjhb register_t r; 93443412Snewton 935125454Sjhb PROC_LOCK(td->td_proc); 936125454Sjhb r = lim_cur(td->td_proc, RLIMIT_DATA); 937125454Sjhb PROC_UNLOCK(td->td_proc); 93871452Sjhb 93943412Snewton if (r == -1) 94043412Snewton r = 0x7fffffff; 94143412Snewton r += (long) vm->vm_daddr; 94243412Snewton if (r < 0) 94343412Snewton r = 0x7fffffff; 94443412Snewton *retval = r; 94543412Snewton return 0; 94643412Snewton } 94743412Snewton 94843412Snewton case SVR4_GDESLIM: 949125454Sjhb PROC_LOCK(td->td_proc); 950125454Sjhb *retval = lim_cur(td->td_proc, RLIMIT_NOFILE); 951125454Sjhb PROC_UNLOCK(td->td_proc); 95243412Snewton if (*retval == -1) 95343412Snewton *retval = 0x7fffffff; 95443412Snewton return 0; 95543412Snewton 95643412Snewton default: 95743412Snewton return EINVAL; 95843412Snewton } 95943412Snewton} 96043412Snewton 96143412Snewtonstatic struct proc * 96243412Snewtonsvr4_pfind(pid) 96343412Snewton pid_t pid; 96443412Snewton{ 96543412Snewton struct proc *p; 96643412Snewton 96743412Snewton /* look in the live processes */ 96871452Sjhb if ((p = pfind(pid)) == NULL) 96971452Sjhb /* look in the zombies */ 97071452Sjhb p = zpfind(pid); 97143412Snewton 97269947Sjake return p; 97343412Snewton} 97443412Snewton 97543412Snewton 97643412Snewtonint 97783366Sjuliansvr4_sys_pgrpsys(td, uap) 97883366Sjulian struct thread *td; 97943412Snewton struct svr4_sys_pgrpsys_args *uap; 98043412Snewton{ 98183366Sjulian int *retval = td->td_retval; 98283366Sjulian struct proc *p = td->td_proc; 98343412Snewton 984107849Salfred switch (uap->cmd) { 98543412Snewton case 1: /* setpgrp() */ 98643412Snewton /* 98743412Snewton * SVR4 setpgrp() (which takes no arguments) has the 98843412Snewton * semantics that the session ID is also created anew, so 98943412Snewton * in almost every sense, setpgrp() is identical to 99043412Snewton * setsid() for SVR4. (Under BSD, the difference is that 99143412Snewton * a setpgid(0,0) will not create a new session.) 99243412Snewton */ 993225617Skmacy sys_setsid(td, NULL); 99443412Snewton /*FALLTHROUGH*/ 99543412Snewton 99643412Snewton case 0: /* getpgrp() */ 99791140Stanimura PROC_LOCK(p); 99843412Snewton *retval = p->p_pgrp->pg_id; 99991140Stanimura PROC_UNLOCK(p); 100043412Snewton return 0; 100143412Snewton 100243412Snewton case 2: /* getsid(pid) */ 1003107849Salfred if (uap->pid == 0) 100489545Stanimura PROC_LOCK(p); 1005107849Salfred else if ((p = svr4_pfind(uap->pid)) == NULL) 100643412Snewton return ESRCH; 100743412Snewton /* 100843412Snewton * This has already been initialized to the pid of 100943412Snewton * the session leader. 101043412Snewton */ 101189541Stanimura *retval = (register_t) p->p_session->s_sid; 101275893Sjhb PROC_UNLOCK(p); 101343412Snewton return 0; 101443412Snewton 101543412Snewton case 3: /* setsid() */ 1016225617Skmacy return sys_setsid(td, NULL); 101743412Snewton 101843412Snewton case 4: /* getpgid(pid) */ 101943412Snewton 1020107849Salfred if (uap->pid == 0) 102189545Stanimura PROC_LOCK(p); 1022107849Salfred else if ((p = svr4_pfind(uap->pid)) == NULL) 102343412Snewton return ESRCH; 102443412Snewton 102543412Snewton *retval = (int) p->p_pgrp->pg_id; 102675893Sjhb PROC_UNLOCK(p); 102743412Snewton return 0; 102843412Snewton 102943412Snewton case 5: /* setpgid(pid, pgid); */ 103043412Snewton { 103143412Snewton struct setpgid_args sa; 103243412Snewton 1033107849Salfred sa.pid = uap->pid; 1034107849Salfred sa.pgid = uap->pgid; 1035225617Skmacy return sys_setpgid(td, &sa); 103643412Snewton } 103743412Snewton 103843412Snewton default: 103943412Snewton return EINVAL; 104043412Snewton } 104143412Snewton} 104243412Snewton 104343412Snewtonstruct svr4_hrtcntl_args { 104443412Snewton int cmd; 104543412Snewton int fun; 104643412Snewton int clk; 104743412Snewton svr4_hrt_interval_t * iv; 104843412Snewton svr4_hrt_time_t * ti; 104943412Snewton}; 105043412Snewton 105143412Snewton 105243412Snewtonstatic int 105383366Sjuliansvr4_hrtcntl(td, uap, retval) 105483366Sjulian struct thread *td; 105543412Snewton struct svr4_hrtcntl_args *uap; 105643412Snewton register_t *retval; 105743412Snewton{ 1058107849Salfred switch (uap->fun) { 105943412Snewton case SVR4_HRT_CNTL_RES: 106043412Snewton DPRINTF(("htrcntl(RES)\n")); 106143412Snewton *retval = SVR4_HRT_USEC; 106243412Snewton return 0; 106343412Snewton 106443412Snewton case SVR4_HRT_CNTL_TOFD: 106543412Snewton DPRINTF(("htrcntl(TOFD)\n")); 106643412Snewton { 106743412Snewton struct timeval tv; 106843412Snewton svr4_hrt_time_t t; 1069107849Salfred if (uap->clk != SVR4_HRT_CLK_STD) { 1070107849Salfred DPRINTF(("clk == %d\n", uap->clk)); 107143412Snewton return EINVAL; 107243412Snewton } 1073107849Salfred if (uap->ti == NULL) { 107443412Snewton DPRINTF(("ti NULL\n")); 107543412Snewton return EINVAL; 107643412Snewton } 107743412Snewton microtime(&tv); 107843412Snewton t.h_sec = tv.tv_sec; 107943412Snewton t.h_rem = tv.tv_usec; 108043412Snewton t.h_res = SVR4_HRT_USEC; 1081107849Salfred return copyout(&t, uap->ti, sizeof(t)); 108243412Snewton } 108343412Snewton 108443412Snewton case SVR4_HRT_CNTL_START: 108543412Snewton DPRINTF(("htrcntl(START)\n")); 108643412Snewton return ENOSYS; 108743412Snewton 108843412Snewton case SVR4_HRT_CNTL_GET: 108943412Snewton DPRINTF(("htrcntl(GET)\n")); 109043412Snewton return ENOSYS; 109143412Snewton default: 1092107849Salfred DPRINTF(("Bad htrcntl command %d\n", uap->fun)); 109343412Snewton return ENOSYS; 109443412Snewton } 109543412Snewton} 109643412Snewton 109743412Snewton 109843412Snewtonint 109983366Sjuliansvr4_sys_hrtsys(td, uap) 110083366Sjulian struct thread *td; 110143412Snewton struct svr4_sys_hrtsys_args *uap; 110243412Snewton{ 110383366Sjulian int *retval = td->td_retval; 110443412Snewton 1105107849Salfred switch (uap->cmd) { 110643412Snewton case SVR4_HRT_CNTL: 110783366Sjulian return svr4_hrtcntl(td, (struct svr4_hrtcntl_args *) uap, 110843412Snewton retval); 110943412Snewton 111043412Snewton case SVR4_HRT_ALRM: 111143412Snewton DPRINTF(("hrtalarm\n")); 111243412Snewton return ENOSYS; 111343412Snewton 111443412Snewton case SVR4_HRT_SLP: 111543412Snewton DPRINTF(("hrtsleep\n")); 111643412Snewton return ENOSYS; 111743412Snewton 111843412Snewton case SVR4_HRT_CAN: 111943412Snewton DPRINTF(("hrtcancel\n")); 112043412Snewton return ENOSYS; 112143412Snewton 112243412Snewton default: 1123107849Salfred DPRINTF(("Bad hrtsys command %d\n", uap->cmd)); 112443412Snewton return EINVAL; 112543412Snewton } 112643412Snewton} 112743412Snewton 112843412Snewton 112943412Snewtonstatic int 1130160510Sjhbsvr4_setinfo(pid, ru, st, s) 1131160510Sjhb pid_t pid; 1132160510Sjhb struct rusage *ru; 113343412Snewton int st; 113443412Snewton svr4_siginfo_t *s; 113543412Snewton{ 113643412Snewton svr4_siginfo_t i; 113743412Snewton int sig; 113843412Snewton 113943412Snewton memset(&i, 0, sizeof(i)); 114043412Snewton 1141151463Sdavidxu i.svr4_si_signo = SVR4_SIGCHLD; 1142151463Sdavidxu i.svr4_si_errno = 0; /* XXX? */ 114343412Snewton 1144160510Sjhb i.svr4_si_pid = pid; 1145160510Sjhb if (ru) { 1146160510Sjhb i.svr4_si_stime = ru->ru_stime.tv_sec; 1147160510Sjhb i.svr4_si_utime = ru->ru_utime.tv_sec; 114843412Snewton } 114943412Snewton 115043412Snewton if (WIFEXITED(st)) { 1151151463Sdavidxu i.svr4_si_status = WEXITSTATUS(st); 1152151463Sdavidxu i.svr4_si_code = SVR4_CLD_EXITED; 115343412Snewton } else if (WIFSTOPPED(st)) { 115443412Snewton sig = WSTOPSIG(st); 115543412Snewton if (sig >= 0 && sig < NSIG) 1156151463Sdavidxu i.svr4_si_status = SVR4_BSD2SVR4_SIG(sig); 115743412Snewton 1158151463Sdavidxu if (i.svr4_si_status == SVR4_SIGCONT) 1159151463Sdavidxu i.svr4_si_code = SVR4_CLD_CONTINUED; 116043412Snewton else 1161151463Sdavidxu i.svr4_si_code = SVR4_CLD_STOPPED; 116243412Snewton } else { 116343412Snewton sig = WTERMSIG(st); 116443412Snewton if (sig >= 0 && sig < NSIG) 1165151463Sdavidxu i.svr4_si_status = SVR4_BSD2SVR4_SIG(sig); 116643412Snewton 116743412Snewton if (WCOREDUMP(st)) 1168151463Sdavidxu i.svr4_si_code = SVR4_CLD_DUMPED; 116943412Snewton else 1170151463Sdavidxu i.svr4_si_code = SVR4_CLD_KILLED; 117143412Snewton } 117243412Snewton 117343412Snewton DPRINTF(("siginfo [pid %ld signo %d code %d errno %d status %d]\n", 1174151463Sdavidxu i.svr4_si_pid, i.svr4_si_signo, i.svr4_si_code, i.svr4_si_errno, 1175151463Sdavidxu i.svr4_si_status)); 117643412Snewton 117743412Snewton return copyout(&i, s, sizeof(i)); 117843412Snewton} 117943412Snewton 118043412Snewton 118143412Snewtonint 118283366Sjuliansvr4_sys_waitsys(td, uap) 118383366Sjulian struct thread *td; 118443412Snewton struct svr4_sys_waitsys_args *uap; 118543412Snewton{ 1186160510Sjhb struct rusage ru; 1187160510Sjhb pid_t pid; 1188160510Sjhb int nfound, status; 118983366Sjulian int error, *retval = td->td_retval; 1190160510Sjhb struct proc *p, *q; 119143412Snewton 1192160510Sjhb DPRINTF(("waitsys(%d, %d, %p, %x)\n", 1193160510Sjhb uap->grp, uap->id, 1194160510Sjhb uap->info, uap->options)); 1195160510Sjhb 1196160510Sjhb q = td->td_proc; 1197107849Salfred switch (uap->grp) { 1198160510Sjhb case SVR4_P_PID: 1199160510Sjhb pid = uap->id; 120043412Snewton break; 120143412Snewton 120243412Snewton case SVR4_P_PGID: 1203160510Sjhb PROC_LOCK(q); 1204160510Sjhb pid = -q->p_pgid; 1205160510Sjhb PROC_UNLOCK(q); 120643412Snewton break; 120743412Snewton 120843412Snewton case SVR4_P_ALL: 1209160510Sjhb pid = WAIT_ANY; 121043412Snewton break; 121143412Snewton 121243412Snewton default: 121343412Snewton return EINVAL; 121443412Snewton } 121543412Snewton 1216160510Sjhb /* Hand off the easy cases to kern_wait(). */ 1217160510Sjhb if (!(uap->options & (SVR4_WNOWAIT)) && 1218160510Sjhb (uap->options & (SVR4_WEXITED | SVR4_WTRAPPED))) { 1219160510Sjhb int options; 122043412Snewton 1221160510Sjhb options = 0; 1222160510Sjhb if (uap->options & SVR4_WSTOPPED) 1223160510Sjhb options |= WUNTRACED; 1224160510Sjhb if (uap->options & SVR4_WCONTINUED) 1225160510Sjhb options |= WCONTINUED; 1226160510Sjhb if (uap->options & SVR4_WNOHANG) 1227160510Sjhb options |= WNOHANG; 1228160510Sjhb 1229160510Sjhb error = kern_wait(td, pid, &status, options, &ru); 1230160510Sjhb if (error) 1231160510Sjhb return (error); 1232160510Sjhb if (uap->options & SVR4_WNOHANG && *retval == 0) 1233160510Sjhb error = svr4_setinfo(*retval, NULL, 0, uap->info); 1234160510Sjhb else 1235160510Sjhb error = svr4_setinfo(*retval, &ru, status, uap->info); 1236160510Sjhb *retval = 0; 1237160510Sjhb return (error); 1238160510Sjhb } 1239160510Sjhb 1240160510Sjhb /* 1241160510Sjhb * Ok, handle the weird cases. Either WNOWAIT is set (meaning we 1242192459Sjhb * just want to see if there is a process to harvest, we don't 1243160510Sjhb * want to actually harvest it), or WEXIT and WTRAPPED are clear 1244160510Sjhb * meaning we want to ignore zombies. Either way, we don't have 1245160510Sjhb * to handle harvesting zombies here. We do have to duplicate the 1246192459Sjhb * other portions of kern_wait() though, especially for WCONTINUED 1247192459Sjhb * and WSTOPPED. 1248160510Sjhb */ 124943412Snewtonloop: 125043412Snewton nfound = 0; 125174927Sjhb sx_slock(&proctree_lock); 1252160510Sjhb LIST_FOREACH(p, &q->p_children, p_sibling) { 1253160510Sjhb PROC_LOCK(p); 1254160510Sjhb if (pid != WAIT_ANY && 1255160510Sjhb p->p_pid != pid && p->p_pgid != -pid) { 1256160510Sjhb PROC_UNLOCK(p); 1257160510Sjhb DPRINTF(("pid %d pgid %d != %d\n", p->p_pid, 1258160510Sjhb p->p_pgid, pid)); 125943412Snewton continue; 126043412Snewton } 1261160510Sjhb if (p_canwait(td, p)) { 1262160510Sjhb PROC_UNLOCK(p); 1263160510Sjhb continue; 1264160510Sjhb } 1265160510Sjhb 126643412Snewton nfound++; 1267160510Sjhb 1268170466Sattilio PROC_SLOCK(p); 1269160510Sjhb /* 1270160510Sjhb * See if we have a zombie. If so, WNOWAIT should be set, 1271160510Sjhb * as otherwise we should have called kern_wait() up above. 1272160510Sjhb */ 1273160510Sjhb if ((p->p_state == PRS_ZOMBIE) && 1274107849Salfred ((uap->options & (SVR4_WEXITED|SVR4_WTRAPPED)))) { 1275170466Sattilio PROC_SUNLOCK(p); 1276160510Sjhb KASSERT(uap->options & SVR4_WNOWAIT, 1277160510Sjhb ("WNOWAIT is clear")); 1278160510Sjhb 1279160510Sjhb /* Found a zombie, so cache info in local variables. */ 1280160510Sjhb pid = p->p_pid; 1281160510Sjhb status = p->p_xstat; 1282170466Sattilio ru = p->p_ru; 1283170472Sattilio PROC_SLOCK(p); 1284160510Sjhb calcru(p, &ru.ru_utime, &ru.ru_stime); 1285170472Sattilio PROC_SUNLOCK(p); 1286160510Sjhb PROC_UNLOCK(p); 128774927Sjhb sx_sunlock(&proctree_lock); 1288160510Sjhb 1289160510Sjhb /* Copy the info out to userland. */ 129043412Snewton *retval = 0; 1291160510Sjhb DPRINTF(("found %d\n", pid)); 1292160510Sjhb return (svr4_setinfo(pid, &ru, status, uap->info)); 1293160510Sjhb } 129443412Snewton 1295160510Sjhb /* 1296160510Sjhb * See if we have a stopped or continued process. 1297160510Sjhb * XXX: This duplicates the same code in kern_wait(). 1298160510Sjhb */ 1299160510Sjhb if ((p->p_flag & P_STOPPED_SIG) && 1300160510Sjhb (p->p_suspcount == p->p_numthreads) && 1301160510Sjhb (p->p_flag & P_WAITED) == 0 && 1302160510Sjhb (p->p_flag & P_TRACED || uap->options & SVR4_WSTOPPED)) { 1303170307Sjeff PROC_SUNLOCK(p); 1304160510Sjhb if (((uap->options & SVR4_WNOWAIT)) == 0) 1305160510Sjhb p->p_flag |= P_WAITED; 1306160510Sjhb sx_sunlock(&proctree_lock); 1307160510Sjhb pid = p->p_pid; 1308160510Sjhb status = W_STOPCODE(p->p_xstat); 1309170466Sattilio ru = p->p_ru; 1310170472Sattilio PROC_SLOCK(p); 1311160510Sjhb calcru(p, &ru.ru_utime, &ru.ru_stime); 1312170472Sattilio PROC_SUNLOCK(p); 1313160510Sjhb PROC_UNLOCK(p); 131443412Snewton 1315160510Sjhb if (((uap->options & SVR4_WNOWAIT)) == 0) { 1316160510Sjhb PROC_LOCK(q); 1317160510Sjhb sigqueue_take(p->p_ksi); 1318160510Sjhb PROC_UNLOCK(q); 131943412Snewton } 132043412Snewton 1321160510Sjhb *retval = 0; 1322160510Sjhb DPRINTF(("jobcontrol %d\n", pid)); 1323160510Sjhb return (svr4_setinfo(pid, &ru, status, uap->info)); 1324160510Sjhb } 1325170307Sjeff PROC_SUNLOCK(p); 1326160510Sjhb if (uap->options & SVR4_WCONTINUED && 1327160510Sjhb (p->p_flag & P_CONTINUED)) { 1328160510Sjhb sx_sunlock(&proctree_lock); 1329160510Sjhb if (((uap->options & SVR4_WNOWAIT)) == 0) 1330160510Sjhb p->p_flag &= ~P_CONTINUED; 1331160510Sjhb pid = p->p_pid; 1332170466Sattilio ru = p->p_ru; 1333160510Sjhb status = SIGCONT; 1334170472Sattilio PROC_SLOCK(p); 1335160510Sjhb calcru(p, &ru.ru_utime, &ru.ru_stime); 1336170472Sattilio PROC_SUNLOCK(p); 1337160510Sjhb PROC_UNLOCK(p); 1338160510Sjhb 1339160510Sjhb if (((uap->options & SVR4_WNOWAIT)) == 0) { 1340160510Sjhb PROC_LOCK(q); 1341160510Sjhb sigqueue_take(p->p_ksi); 1342160510Sjhb PROC_UNLOCK(q); 134373907Sjhb } 134443412Snewton 134543412Snewton *retval = 0; 1346160510Sjhb DPRINTF(("jobcontrol %d\n", pid)); 1347160510Sjhb return (svr4_setinfo(pid, &ru, status, uap->info)); 134843412Snewton } 1349160510Sjhb PROC_UNLOCK(p); 135043412Snewton } 135143412Snewton 1352160510Sjhb if (nfound == 0) { 1353160510Sjhb sx_sunlock(&proctree_lock); 1354160510Sjhb return (ECHILD); 1355160510Sjhb } 135643412Snewton 1357107849Salfred if (uap->options & SVR4_WNOHANG) { 1358160510Sjhb sx_sunlock(&proctree_lock); 135943412Snewton *retval = 0; 1360160510Sjhb return (svr4_setinfo(0, NULL, 0, uap->info)); 136143412Snewton } 136243412Snewton 1363160510Sjhb PROC_LOCK(q); 1364160510Sjhb sx_sunlock(&proctree_lock); 1365160510Sjhb if (q->p_flag & P_STATCHILD) { 1366160510Sjhb q->p_flag &= ~P_STATCHILD; 1367160510Sjhb error = 0; 1368160510Sjhb } else 1369160510Sjhb error = msleep(q, &q->p_mtx, PWAIT | PCATCH, "svr4_wait", 0); 1370160510Sjhb PROC_UNLOCK(q); 1371160510Sjhb if (error) 137243412Snewton return error; 137343412Snewton goto loop; 137443412Snewton} 137543412Snewton 137643412Snewton 137743412Snewtonstatic void 137843412Snewtonbsd_statfs_to_svr4_statvfs(bfs, sfs) 137943412Snewton const struct statfs *bfs; 138043412Snewton struct svr4_statvfs *sfs; 138143412Snewton{ 138243412Snewton sfs->f_bsize = bfs->f_iosize; /* XXX */ 138343412Snewton sfs->f_frsize = bfs->f_bsize; 138443412Snewton sfs->f_blocks = bfs->f_blocks; 138543412Snewton sfs->f_bfree = bfs->f_bfree; 138643412Snewton sfs->f_bavail = bfs->f_bavail; 138743412Snewton sfs->f_files = bfs->f_files; 138843412Snewton sfs->f_ffree = bfs->f_ffree; 138943412Snewton sfs->f_favail = bfs->f_ffree; 139043412Snewton sfs->f_fsid = bfs->f_fsid.val[0]; 139143412Snewton memcpy(sfs->f_basetype, bfs->f_fstypename, sizeof(sfs->f_basetype)); 139243412Snewton sfs->f_flag = 0; 139343412Snewton if (bfs->f_flags & MNT_RDONLY) 139443412Snewton sfs->f_flag |= SVR4_ST_RDONLY; 139543412Snewton if (bfs->f_flags & MNT_NOSUID) 139643412Snewton sfs->f_flag |= SVR4_ST_NOSUID; 139743412Snewton sfs->f_namemax = MAXNAMLEN; 139843412Snewton memcpy(sfs->f_fstr, bfs->f_fstypename, sizeof(sfs->f_fstr)); /* XXX */ 139943412Snewton memset(sfs->f_filler, 0, sizeof(sfs->f_filler)); 140043412Snewton} 140143412Snewton 140243412Snewton 140343412Snewtonstatic void 140443412Snewtonbsd_statfs_to_svr4_statvfs64(bfs, sfs) 140543412Snewton const struct statfs *bfs; 140643412Snewton struct svr4_statvfs64 *sfs; 140743412Snewton{ 140843412Snewton sfs->f_bsize = bfs->f_iosize; /* XXX */ 140943412Snewton sfs->f_frsize = bfs->f_bsize; 141043412Snewton sfs->f_blocks = bfs->f_blocks; 141143412Snewton sfs->f_bfree = bfs->f_bfree; 141243412Snewton sfs->f_bavail = bfs->f_bavail; 141343412Snewton sfs->f_files = bfs->f_files; 141443412Snewton sfs->f_ffree = bfs->f_ffree; 141543412Snewton sfs->f_favail = bfs->f_ffree; 141643412Snewton sfs->f_fsid = bfs->f_fsid.val[0]; 141743412Snewton memcpy(sfs->f_basetype, bfs->f_fstypename, sizeof(sfs->f_basetype)); 141843412Snewton sfs->f_flag = 0; 141943412Snewton if (bfs->f_flags & MNT_RDONLY) 142043412Snewton sfs->f_flag |= SVR4_ST_RDONLY; 142143412Snewton if (bfs->f_flags & MNT_NOSUID) 142243412Snewton sfs->f_flag |= SVR4_ST_NOSUID; 142343412Snewton sfs->f_namemax = MAXNAMLEN; 142443412Snewton memcpy(sfs->f_fstr, bfs->f_fstypename, sizeof(sfs->f_fstr)); /* XXX */ 142543412Snewton memset(sfs->f_filler, 0, sizeof(sfs->f_filler)); 142643412Snewton} 142743412Snewton 142843412Snewton 142943412Snewtonint 143083366Sjuliansvr4_sys_statvfs(td, uap) 143183366Sjulian struct thread *td; 143243412Snewton struct svr4_sys_statvfs_args *uap; 143343412Snewton{ 1434141486Sjhb struct svr4_statvfs sfs; 143543412Snewton struct statfs bfs; 1436141486Sjhb char *path; 143743412Snewton int error; 143843412Snewton 1439141486Sjhb CHECKALTEXIST(td, uap->path, &path); 144043412Snewton 1441141486Sjhb error = kern_statfs(td, path, UIO_SYSSPACE, &bfs); 1442141486Sjhb free(path, M_TEMP); 1443141486Sjhb if (error) 1444141486Sjhb return (error); 144543412Snewton bsd_statfs_to_svr4_statvfs(&bfs, &sfs); 1446107849Salfred return copyout(&sfs, uap->fs, sizeof(sfs)); 144743412Snewton} 144843412Snewton 144943412Snewton 145043412Snewtonint 145183366Sjuliansvr4_sys_fstatvfs(td, uap) 145283366Sjulian struct thread *td; 145343412Snewton struct svr4_sys_fstatvfs_args *uap; 145443412Snewton{ 1455141486Sjhb struct svr4_statvfs sfs; 145643412Snewton struct statfs bfs; 145743412Snewton int error; 145843412Snewton 1459141486Sjhb error = kern_fstatfs(td, uap->fd, &bfs); 1460141486Sjhb if (error) 1461141486Sjhb return (error); 146243412Snewton bsd_statfs_to_svr4_statvfs(&bfs, &sfs); 1463107849Salfred return copyout(&sfs, uap->fs, sizeof(sfs)); 146443412Snewton} 146543412Snewton 146643412Snewton 146743412Snewtonint 146883366Sjuliansvr4_sys_statvfs64(td, uap) 146983366Sjulian struct thread *td; 147043412Snewton struct svr4_sys_statvfs64_args *uap; 147143412Snewton{ 1472141486Sjhb struct svr4_statvfs64 sfs; 147343412Snewton struct statfs bfs; 1474141486Sjhb char *path; 147543412Snewton int error; 147643412Snewton 1477141486Sjhb CHECKALTEXIST(td, uap->path, &path); 147843412Snewton 1479141486Sjhb error = kern_statfs(td, path, UIO_SYSSPACE, &bfs); 1480141486Sjhb free(path, M_TEMP); 1481141486Sjhb if (error) 1482141486Sjhb return (error); 148343412Snewton bsd_statfs_to_svr4_statvfs64(&bfs, &sfs); 1484107849Salfred return copyout(&sfs, uap->fs, sizeof(sfs)); 148543412Snewton} 148643412Snewton 148743412Snewton 148843412Snewtonint 148983366Sjuliansvr4_sys_fstatvfs64(td, uap) 149083366Sjulian struct thread *td; 149143412Snewton struct svr4_sys_fstatvfs64_args *uap; 149243412Snewton{ 1493141486Sjhb struct svr4_statvfs64 sfs; 149443412Snewton struct statfs bfs; 149543412Snewton int error; 149643412Snewton 1497141486Sjhb error = kern_fstatfs(td, uap->fd, &bfs); 1498141486Sjhb if (error) 1499141486Sjhb return (error); 150043412Snewton bsd_statfs_to_svr4_statvfs64(&bfs, &sfs); 1501107849Salfred return copyout(&sfs, uap->fs, sizeof(sfs)); 150243412Snewton} 150343412Snewton 150443412Snewtonint 150583366Sjuliansvr4_sys_alarm(td, uap) 150683366Sjulian struct thread *td; 150743412Snewton struct svr4_sys_alarm_args *uap; 150843412Snewton{ 1509141486Sjhb struct itimerval itv, oitv; 151043412Snewton int error; 151143412Snewton 1512141486Sjhb timevalclear(&itv.it_interval); 1513141486Sjhb itv.it_value.tv_sec = uap->sec; 1514141486Sjhb itv.it_value.tv_usec = 0; 1515141486Sjhb error = kern_setitimer(td, ITIMER_REAL, &itv, &oitv); 151643412Snewton if (error) 1517141486Sjhb return (error); 1518141486Sjhb if (oitv.it_value.tv_usec != 0) 1519141486Sjhb oitv.it_value.tv_sec++; 1520141486Sjhb td->td_retval[0] = oitv.it_value.tv_sec; 1521141486Sjhb return (0); 152243412Snewton} 152343412Snewton 152443412Snewtonint 152583366Sjuliansvr4_sys_gettimeofday(td, uap) 152683366Sjulian struct thread *td; 152743412Snewton struct svr4_sys_gettimeofday_args *uap; 152843412Snewton{ 1529107849Salfred if (uap->tp) { 153043412Snewton struct timeval atv; 153143412Snewton 153243412Snewton microtime(&atv); 1533107849Salfred return copyout(&atv, uap->tp, sizeof (atv)); 153443412Snewton } 153543412Snewton 153643412Snewton return 0; 153743412Snewton} 153843412Snewton 153943412Snewtonint 154083366Sjuliansvr4_sys_facl(td, uap) 154183366Sjulian struct thread *td; 154243412Snewton struct svr4_sys_facl_args *uap; 154343412Snewton{ 154443412Snewton int *retval; 154543412Snewton 154683366Sjulian retval = td->td_retval; 154743412Snewton *retval = 0; 154843412Snewton 1549107849Salfred switch (uap->cmd) { 155043412Snewton case SVR4_SYS_SETACL: 155143412Snewton /* We don't support acls on any filesystem */ 155243412Snewton return ENOSYS; 155343412Snewton 155443412Snewton case SVR4_SYS_GETACL: 1555107849Salfred return copyout(retval, &uap->num, 1556107849Salfred sizeof(uap->num)); 155743412Snewton 155843412Snewton case SVR4_SYS_GETACLCNT: 155943412Snewton return 0; 156043412Snewton 156143412Snewton default: 156243412Snewton return EINVAL; 156343412Snewton } 156443412Snewton} 156543412Snewton 156643412Snewton 156743412Snewtonint 156883366Sjuliansvr4_sys_acl(td, uap) 156983366Sjulian struct thread *td; 157043412Snewton struct svr4_sys_acl_args *uap; 157143412Snewton{ 157243412Snewton /* XXX: for now the same */ 157383366Sjulian return svr4_sys_facl(td, (struct svr4_sys_facl_args *)uap); 157443412Snewton} 157543412Snewton 157643412Snewtonint 157783366Sjuliansvr4_sys_auditsys(td, uap) 157883366Sjulian struct thread *td; 157943412Snewton struct svr4_sys_auditsys_args *uap; 158043412Snewton{ 158143412Snewton /* 158243412Snewton * XXX: Big brother is *not* watching. 158343412Snewton */ 158443412Snewton return 0; 158543412Snewton} 158643412Snewton 158743412Snewtonint 158883366Sjuliansvr4_sys_memcntl(td, uap) 158983366Sjulian struct thread *td; 159043412Snewton struct svr4_sys_memcntl_args *uap; 159143412Snewton{ 1592107849Salfred switch (uap->cmd) { 159343412Snewton case SVR4_MC_SYNC: 159443412Snewton { 159543412Snewton struct msync_args msa; 159643412Snewton 1597107849Salfred msa.addr = uap->addr; 1598107849Salfred msa.len = uap->len; 1599107849Salfred msa.flags = (int)uap->arg; 160043412Snewton 1601225617Skmacy return sys_msync(td, &msa); 160243412Snewton } 160343412Snewton case SVR4_MC_ADVISE: 160443412Snewton { 160543412Snewton struct madvise_args maa; 160643412Snewton 1607107849Salfred maa.addr = uap->addr; 1608107849Salfred maa.len = uap->len; 1609107849Salfred maa.behav = (int)uap->arg; 161043412Snewton 1611225617Skmacy return sys_madvise(td, &maa); 161243412Snewton } 161343412Snewton case SVR4_MC_LOCK: 161443412Snewton case SVR4_MC_UNLOCK: 161543412Snewton case SVR4_MC_LOCKAS: 161643412Snewton case SVR4_MC_UNLOCKAS: 161743412Snewton return EOPNOTSUPP; 161843412Snewton default: 161943412Snewton return ENOSYS; 162043412Snewton } 162143412Snewton} 162243412Snewton 162343412Snewton 162443412Snewtonint 162583366Sjuliansvr4_sys_nice(td, uap) 162683366Sjulian struct thread *td; 162743412Snewton struct svr4_sys_nice_args *uap; 162843412Snewton{ 162943412Snewton struct setpriority_args ap; 163043412Snewton int error; 163143412Snewton 1632107849Salfred ap.which = PRIO_PROCESS; 1633107849Salfred ap.who = 0; 1634107849Salfred ap.prio = uap->prio; 163543412Snewton 1636225617Skmacy if ((error = sys_setpriority(td, &ap)) != 0) 163743412Snewton return error; 163843412Snewton 163943412Snewton /* the cast is stupid, but the structures are the same */ 1640225617Skmacy if ((error = sys_getpriority(td, (struct getpriority_args *)&ap)) != 0) 164143412Snewton return error; 164243412Snewton 164343412Snewton return 0; 164443412Snewton} 164543412Snewton 164643412Snewtonint 164783366Sjuliansvr4_sys_resolvepath(td, uap) 164883366Sjulian struct thread *td; 164943412Snewton struct svr4_sys_resolvepath_args *uap; 165043412Snewton{ 165143412Snewton struct nameidata nd; 165283366Sjulian int error, *retval = td->td_retval; 1653121275Stjr unsigned int ncopy; 165443412Snewton 1655160511Sjhb NDINIT(&nd, LOOKUP, NOFOLLOW | SAVENAME | MPSAFE, UIO_USERSPACE, 1656107849Salfred uap->path, td); 165743412Snewton 165843412Snewton if ((error = namei(&nd)) != 0) 1659192455Sjhb return (error); 1660192455Sjhb NDFREE(&nd, NDF_NO_FREE_PNBUF); 1661192455Sjhb VFS_UNLOCK_GIANT(NDHASGIANT(&nd)); 166243412Snewton 1663121275Stjr ncopy = min(uap->bufsiz, strlen(nd.ni_cnd.cn_pnbuf) + 1); 1664121275Stjr if ((error = copyout(nd.ni_cnd.cn_pnbuf, uap->buf, ncopy)) != 0) 166543412Snewton goto bad; 166643412Snewton 1667121275Stjr *retval = ncopy; 166843412Snewtonbad: 166954655Seivind NDFREE(&nd, NDF_ONLY_PNBUF); 167043412Snewton return error; 167143412Snewton} 1672