1139743Simp/*- 243412Snewton * Copyright (c) 1998 Mark Newton 343412Snewton * Copyright (c) 1994, 1997 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. All advertising materials mentioning features or use of this software 1543412Snewton * must display the following acknowledgement: 1643412Snewton * This product includes software developed by Christos Zoulas. 1743412Snewton * 4. The name of the author may not be used to endorse or promote products 1843412Snewton * derived from this software without specific prior written permission. 1943412Snewton * 2043412Snewton * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2143412Snewton * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2243412Snewton * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2343412Snewton * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2443412Snewton * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2543412Snewton * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2643412Snewton * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2743412Snewton * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2843412Snewton * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2943412Snewton * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3043412Snewton */ 31101709Srwatson 32116174Sobrien#include <sys/cdefs.h> 33116174Sobrien__FBSDID("$FreeBSD$"); 34116174Sobrien 3543412Snewton#include <sys/param.h> 36224778Srwatson#include <sys/capability.h> 3743412Snewton#include <sys/systm.h> 3843412Snewton#include <sys/file.h> 3943412Snewton#include <sys/filedesc.h> 4043412Snewton/*#include <sys/ioctl.h>*/ 4176166Smarkm#include <sys/lock.h> 42141486Sjhb#include <sys/malloc.h> 4343412Snewton#include <sys/mount.h> 4476166Smarkm#include <sys/mutex.h> 4576166Smarkm#include <sys/namei.h> 46164033Srwatson#include <sys/priv.h> 4776166Smarkm#include <sys/proc.h> 4876166Smarkm#include <sys/stat.h> 49134266Sjhb#include <sys/syscallsubr.h> 5076166Smarkm#include <sys/unistd.h> 5143412Snewton#include <sys/vnode.h> 5243412Snewton 5343412Snewton#include <sys/sysproto.h> 5443412Snewton 5565302Sobrien#include <compat/svr4/svr4.h> 5665302Sobrien#include <compat/svr4/svr4_types.h> 5765302Sobrien#include <compat/svr4/svr4_signal.h> 5865302Sobrien#include <compat/svr4/svr4_proto.h> 5965302Sobrien#include <compat/svr4/svr4_util.h> 6065302Sobrien#include <compat/svr4/svr4_fcntl.h> 6143412Snewton 62163606Srwatson#include <security/mac/mac_framework.h> 63163606Srwatson 6492761Salfredstatic int svr4_to_bsd_flags(int); 6592761Salfredstatic u_long svr4_to_bsd_cmd(u_long); 6692761Salfredstatic int fd_revoke(struct thread *, int); 6792761Salfredstatic int fd_truncate(struct thread *, int, struct flock *); 6892761Salfredstatic int bsd_to_svr4_flags(int); 6992761Salfredstatic void bsd_to_svr4_flock(struct flock *, struct svr4_flock *); 7092761Salfredstatic void svr4_to_bsd_flock(struct svr4_flock *, struct flock *); 7192761Salfredstatic void bsd_to_svr4_flock64(struct flock *, struct svr4_flock64 *); 7292761Salfredstatic void svr4_to_bsd_flock64(struct svr4_flock64 *, struct flock *); 7343412Snewton 7443412Snewtonstatic u_long 7543412Snewtonsvr4_to_bsd_cmd(cmd) 7643412Snewton u_long cmd; 7743412Snewton{ 7843412Snewton switch (cmd) { 7943412Snewton case SVR4_F_DUPFD: 8043412Snewton return F_DUPFD; 81177314Santoine case SVR4_F_DUP2FD: 82177314Santoine return F_DUP2FD; 8343412Snewton case SVR4_F_GETFD: 8443412Snewton return F_GETFD; 8543412Snewton case SVR4_F_SETFD: 8643412Snewton return F_SETFD; 8743412Snewton case SVR4_F_GETFL: 8843412Snewton return F_GETFL; 8943412Snewton case SVR4_F_SETFL: 9043412Snewton return F_SETFL; 9143412Snewton case SVR4_F_GETLK: 9243412Snewton return F_GETLK; 9343412Snewton case SVR4_F_SETLK: 9443412Snewton return F_SETLK; 9543412Snewton case SVR4_F_SETLKW: 9643412Snewton return F_SETLKW; 9743412Snewton default: 9843412Snewton return -1; 9943412Snewton } 10043412Snewton} 10143412Snewton 10243412Snewtonstatic int 10343412Snewtonsvr4_to_bsd_flags(l) 10443412Snewton int l; 10543412Snewton{ 10643412Snewton int r = 0; 10743412Snewton r |= (l & SVR4_O_RDONLY) ? O_RDONLY : 0; 10843412Snewton r |= (l & SVR4_O_WRONLY) ? O_WRONLY : 0; 10943412Snewton r |= (l & SVR4_O_RDWR) ? O_RDWR : 0; 11043412Snewton r |= (l & SVR4_O_NDELAY) ? O_NONBLOCK : 0; 11143412Snewton r |= (l & SVR4_O_APPEND) ? O_APPEND : 0; 11243412Snewton r |= (l & SVR4_O_SYNC) ? O_FSYNC : 0; 11343412Snewton r |= (l & SVR4_O_NONBLOCK) ? O_NONBLOCK : 0; 11443412Snewton r |= (l & SVR4_O_PRIV) ? O_EXLOCK : 0; 11543412Snewton r |= (l & SVR4_O_CREAT) ? O_CREAT : 0; 11643412Snewton r |= (l & SVR4_O_TRUNC) ? O_TRUNC : 0; 11743412Snewton r |= (l & SVR4_O_EXCL) ? O_EXCL : 0; 11843412Snewton r |= (l & SVR4_O_NOCTTY) ? O_NOCTTY : 0; 11943412Snewton return r; 12043412Snewton} 12143412Snewton 12243412Snewtonstatic int 12343412Snewtonbsd_to_svr4_flags(l) 12443412Snewton int l; 12543412Snewton{ 12643412Snewton int r = 0; 12743412Snewton r |= (l & O_RDONLY) ? SVR4_O_RDONLY : 0; 12843412Snewton r |= (l & O_WRONLY) ? SVR4_O_WRONLY : 0; 12943412Snewton r |= (l & O_RDWR) ? SVR4_O_RDWR : 0; 13043412Snewton r |= (l & O_NDELAY) ? SVR4_O_NONBLOCK : 0; 13143412Snewton r |= (l & O_APPEND) ? SVR4_O_APPEND : 0; 13243412Snewton r |= (l & O_FSYNC) ? SVR4_O_SYNC : 0; 13343412Snewton r |= (l & O_NONBLOCK) ? SVR4_O_NONBLOCK : 0; 13443412Snewton r |= (l & O_EXLOCK) ? SVR4_O_PRIV : 0; 13543412Snewton r |= (l & O_CREAT) ? SVR4_O_CREAT : 0; 13643412Snewton r |= (l & O_TRUNC) ? SVR4_O_TRUNC : 0; 13743412Snewton r |= (l & O_EXCL) ? SVR4_O_EXCL : 0; 13843412Snewton r |= (l & O_NOCTTY) ? SVR4_O_NOCTTY : 0; 13943412Snewton return r; 14043412Snewton} 14143412Snewton 14243412Snewton 14343412Snewtonstatic void 14443412Snewtonbsd_to_svr4_flock(iflp, oflp) 14543412Snewton struct flock *iflp; 14643412Snewton struct svr4_flock *oflp; 14743412Snewton{ 14843412Snewton switch (iflp->l_type) { 14943412Snewton case F_RDLCK: 15043412Snewton oflp->l_type = SVR4_F_RDLCK; 15143412Snewton break; 15243412Snewton case F_WRLCK: 15343412Snewton oflp->l_type = SVR4_F_WRLCK; 15443412Snewton break; 15543412Snewton case F_UNLCK: 15643412Snewton oflp->l_type = SVR4_F_UNLCK; 15743412Snewton break; 15843412Snewton default: 15943412Snewton oflp->l_type = -1; 16043412Snewton break; 16143412Snewton } 16243412Snewton 16343412Snewton oflp->l_whence = (short) iflp->l_whence; 16443412Snewton oflp->l_start = (svr4_off_t) iflp->l_start; 16543412Snewton oflp->l_len = (svr4_off_t) iflp->l_len; 16643412Snewton oflp->l_sysid = 0; 16743412Snewton oflp->l_pid = (svr4_pid_t) iflp->l_pid; 16843412Snewton} 16943412Snewton 17043412Snewton 17143412Snewtonstatic void 17243412Snewtonsvr4_to_bsd_flock(iflp, oflp) 17343412Snewton struct svr4_flock *iflp; 17443412Snewton struct flock *oflp; 17543412Snewton{ 17643412Snewton switch (iflp->l_type) { 17743412Snewton case SVR4_F_RDLCK: 17843412Snewton oflp->l_type = F_RDLCK; 17943412Snewton break; 18043412Snewton case SVR4_F_WRLCK: 18143412Snewton oflp->l_type = F_WRLCK; 18243412Snewton break; 18343412Snewton case SVR4_F_UNLCK: 18443412Snewton oflp->l_type = F_UNLCK; 18543412Snewton break; 18643412Snewton default: 18743412Snewton oflp->l_type = -1; 18843412Snewton break; 18943412Snewton } 19043412Snewton 19143412Snewton oflp->l_whence = iflp->l_whence; 19243412Snewton oflp->l_start = (off_t) iflp->l_start; 19343412Snewton oflp->l_len = (off_t) iflp->l_len; 19443412Snewton oflp->l_pid = (pid_t) iflp->l_pid; 195177633Sdfr oflp->l_sysid = iflp->l_sysid; 19643412Snewton} 19743412Snewton 19843412Snewtonstatic void 19943412Snewtonbsd_to_svr4_flock64(iflp, oflp) 20043412Snewton struct flock *iflp; 20143412Snewton struct svr4_flock64 *oflp; 20243412Snewton{ 20343412Snewton switch (iflp->l_type) { 20443412Snewton case F_RDLCK: 20543412Snewton oflp->l_type = SVR4_F_RDLCK; 20643412Snewton break; 20743412Snewton case F_WRLCK: 20843412Snewton oflp->l_type = SVR4_F_WRLCK; 20943412Snewton break; 21043412Snewton case F_UNLCK: 21143412Snewton oflp->l_type = SVR4_F_UNLCK; 21243412Snewton break; 21343412Snewton default: 21443412Snewton oflp->l_type = -1; 21543412Snewton break; 21643412Snewton } 21743412Snewton 21843412Snewton oflp->l_whence = (short) iflp->l_whence; 21943412Snewton oflp->l_start = (svr4_off64_t) iflp->l_start; 22043412Snewton oflp->l_len = (svr4_off64_t) iflp->l_len; 221177633Sdfr oflp->l_sysid = iflp->l_sysid; 22243412Snewton oflp->l_pid = (svr4_pid_t) iflp->l_pid; 22343412Snewton} 22443412Snewton 22543412Snewton 22643412Snewtonstatic void 22743412Snewtonsvr4_to_bsd_flock64(iflp, oflp) 22843412Snewton struct svr4_flock64 *iflp; 22943412Snewton struct flock *oflp; 23043412Snewton{ 23143412Snewton switch (iflp->l_type) { 23243412Snewton case SVR4_F_RDLCK: 23343412Snewton oflp->l_type = F_RDLCK; 23443412Snewton break; 23543412Snewton case SVR4_F_WRLCK: 23643412Snewton oflp->l_type = F_WRLCK; 23743412Snewton break; 23843412Snewton case SVR4_F_UNLCK: 23943412Snewton oflp->l_type = F_UNLCK; 24043412Snewton break; 24143412Snewton default: 24243412Snewton oflp->l_type = -1; 24343412Snewton break; 24443412Snewton } 24543412Snewton 24643412Snewton oflp->l_whence = iflp->l_whence; 24743412Snewton oflp->l_start = (off_t) iflp->l_start; 24843412Snewton oflp->l_len = (off_t) iflp->l_len; 24943412Snewton oflp->l_pid = (pid_t) iflp->l_pid; 25043412Snewton 25143412Snewton} 25243412Snewton 25343412Snewton 25443412Snewtonstatic int 25583366Sjulianfd_revoke(td, fd) 25683366Sjulian struct thread *td; 25743412Snewton int fd; 25843412Snewton{ 25943412Snewton struct vnode *vp; 26062976Smckusick struct mount *mp; 26143412Snewton struct vattr vattr; 262255219Spjd cap_rights_t rights; 26343412Snewton int error, *retval; 26443412Snewton 26583366Sjulian retval = td->td_retval; 266224778Srwatson /* 267224778Srwatson * If we ever want to support Capsicum on SVR4 processes (unlikely) 268224778Srwatson * or FreeBSD grows a native frevoke() (more likely), we will need a 269247602Spjd * CAP_FREVOKE here. 270224778Srwatson * 271255219Spjd * In the meantime, use CAP_ALL(): if a SVR4 process wants to 272224778Srwatson * do an frevoke(), it needs to do it on either a regular file 273224778Srwatson * descriptor or a fully-privileged capability (which is effectively 274224778Srwatson * the same as a non-capability-restricted file descriptor). 275224778Srwatson */ 276255219Spjd CAP_ALL(&rights); 277255219Spjd if ((error = fgetvp(td, fd, &rights, &vp)) != 0) 27889319Salfred return (error); 27943412Snewton 28043412Snewton if (vp->v_type != VCHR && vp->v_type != VBLK) { 28143412Snewton error = EINVAL; 28243412Snewton goto out; 28343412Snewton } 28443412Snewton 285101709Srwatson#ifdef MAC 286175202Sattilio vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 287172930Srwatson error = mac_vnode_check_revoke(td->td_ucred, vp); 288175294Sattilio VOP_UNLOCK(vp, 0); 289101709Srwatson if (error) 290101709Srwatson goto out; 291101709Srwatson#endif 292101709Srwatson 293182371Sattilio if ((error = VOP_GETATTR(vp, &vattr, td->td_ucred)) != 0) 29443412Snewton goto out; 29543412Snewton 29691406Sjhb if (td->td_ucred->cr_uid != vattr.va_uid && 297170587Srwatson (error = priv_check(td, PRIV_VFS_ADMIN)) != 0) 29843412Snewton goto out; 29943412Snewton 30062976Smckusick if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 30162976Smckusick goto out; 30250405Sphk if (vcount(vp) > 1) 30343412Snewton VOP_REVOKE(vp, REVOKEALL); 30462976Smckusick vn_finished_write(mp); 30543412Snewtonout: 30643412Snewton vrele(vp); 30743412Snewton return error; 30843412Snewton} 30943412Snewton 31043412Snewton 31143412Snewtonstatic int 31283366Sjulianfd_truncate(td, fd, flp) 31383366Sjulian struct thread *td; 31443412Snewton int fd; 31543412Snewton struct flock *flp; 31643412Snewton{ 31743412Snewton off_t start, length; 31889534Salfred struct file *fp; 31943412Snewton struct vnode *vp; 32043412Snewton struct vattr vattr; 32143412Snewton int error, *retval; 32243412Snewton struct ftruncate_args ft; 323255219Spjd cap_rights_t rights; 32443412Snewton 32583366Sjulian retval = td->td_retval; 32643412Snewton 32743412Snewton /* 32843412Snewton * We only support truncating the file. 32943412Snewton */ 330255219Spjd error = fget(td, fd, cap_rights_init(&rights, CAP_FTRUNCATE), &fp); 331255219Spjd if (error != 0) 33289319Salfred return (error); 33343412Snewton 334116678Sphk vp = fp->f_vnode; 33589534Salfred 33689534Salfred if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) { 33789534Salfred fdrop(fp, td); 33843412Snewton return ESPIPE; 33989306Salfred } 34043412Snewton 341182371Sattilio if ((error = VOP_GETATTR(vp, &vattr, td->td_ucred)) != 0) { 34289534Salfred fdrop(fp, td); 34343412Snewton return error; 34489306Salfred } 34543412Snewton 34643412Snewton length = vattr.va_size; 34743412Snewton 34843412Snewton switch (flp->l_whence) { 34943412Snewton case SEEK_CUR: 35043412Snewton start = fp->f_offset + flp->l_start; 35143412Snewton break; 35243412Snewton 35343412Snewton case SEEK_END: 35443412Snewton start = flp->l_start + length; 35543412Snewton break; 35643412Snewton 35743412Snewton case SEEK_SET: 35843412Snewton start = flp->l_start; 35943412Snewton break; 36043412Snewton 36143412Snewton default: 36289534Salfred fdrop(fp, td); 36343412Snewton return EINVAL; 36443412Snewton } 36543412Snewton 36643412Snewton if (start + flp->l_len < length) { 36743412Snewton /* We don't support free'ing in the middle of the file */ 36889534Salfred fdrop(fp, td); 36943412Snewton return EINVAL; 37043412Snewton } 37143412Snewton 372107849Salfred ft.fd = fd; 373107849Salfred ft.length = start; 37443412Snewton 375225617Skmacy error = sys_ftruncate(td, &ft); 37689306Salfred 37789534Salfred fdrop(fp, td); 37889306Salfred return (error); 37943412Snewton} 38043412Snewton 38143412Snewtonint 38283366Sjuliansvr4_sys_open(td, uap) 383193014Sdelphij struct thread *td; 38443412Snewton struct svr4_sys_open_args *uap; 38543412Snewton{ 38683366Sjulian struct proc *p = td->td_proc; 387141486Sjhb char *newpath; 388141486Sjhb int bsd_flags, error, retval; 38943412Snewton 390141486Sjhb CHECKALTEXIST(td, uap->path, &newpath); 39143412Snewton 392141486Sjhb bsd_flags = svr4_to_bsd_flags(uap->flags); 393141486Sjhb error = kern_open(td, newpath, UIO_SYSSPACE, bsd_flags, uap->mode); 394141486Sjhb free(newpath, M_TEMP); 39543412Snewton 39643412Snewton if (error) { 397150663Srwatson /* uprintf("svr4_open(%s, 0x%0x, 0%o): %d\n", uap->path, 398150663Srwatson uap->flags, uap->mode, error);*/ 39943412Snewton return error; 40043412Snewton } 40143412Snewton 40283366Sjulian retval = td->td_retval[0]; 40343412Snewton 40471454Sjhb PROC_LOCK(p); 405141486Sjhb if (!(bsd_flags & O_NOCTTY) && SESS_LEADER(p) && 406141486Sjhb !(p->p_flag & P_CONTROLT)) { 40743412Snewton#if defined(NOTYET) 408255219Spjd cap_rights_t rights; 409255219Spjd struct file *fp; 41043412Snewton 411255219Spjd error = fget(td, retval, 412255219Spjd cap_rights_init(&rights, CAP_IOCTL), &fp); 41371454Sjhb PROC_UNLOCK(p); 41489306Salfred /* 41589306Salfred * we may have lost a race the above open() and 41689306Salfred * another thread issuing a close() 41789306Salfred */ 41889319Salfred if (error) 41989306Salfred return (EBADF); /* XXX: correct errno? */ 42043412Snewton /* ignore any error, just give it a try */ 42143412Snewton if (fp->f_type == DTYPE_VNODE) 422102003Srwatson fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td->td_ucred, 423102003Srwatson td); 42489306Salfred fdrop(fp, td); 42589306Salfred } else { 42671454Sjhb PROC_UNLOCK(p); 42789306Salfred } 42871454Sjhb#else 42971454Sjhb } 43071454Sjhb PROC_UNLOCK(p); 43143412Snewton#endif 43243412Snewton return error; 43343412Snewton} 43443412Snewton 43543412Snewtonint 43683366Sjuliansvr4_sys_open64(td, uap) 437193014Sdelphij struct thread *td; 43843412Snewton struct svr4_sys_open64_args *uap; 43943412Snewton{ 44083366Sjulian return svr4_sys_open(td, (struct svr4_sys_open_args *)uap); 44143412Snewton} 44243412Snewton 44343412Snewtonint 44483366Sjuliansvr4_sys_creat(td, uap) 445193014Sdelphij struct thread *td; 44643412Snewton struct svr4_sys_creat_args *uap; 44743412Snewton{ 448141486Sjhb char *newpath; 449141486Sjhb int error; 45043412Snewton 451141486Sjhb CHECKALTEXIST(td, uap->path, &newpath); 45243412Snewton 453141486Sjhb error = kern_open(td, newpath, UIO_SYSSPACE, O_WRONLY | O_CREAT | 454141486Sjhb O_TRUNC, uap->mode); 455141486Sjhb free(newpath, M_TEMP); 456141486Sjhb return (error); 45743412Snewton} 45843412Snewton 45943412Snewtonint 46083366Sjuliansvr4_sys_creat64(td, uap) 461193014Sdelphij struct thread *td; 46243412Snewton struct svr4_sys_creat64_args *uap; 46343412Snewton{ 46483366Sjulian return svr4_sys_creat(td, (struct svr4_sys_creat_args *)uap); 46543412Snewton} 46643412Snewton 46743412Snewtonint 46883366Sjuliansvr4_sys_llseek(td, uap) 469193014Sdelphij struct thread *td; 47071454Sjhb struct svr4_sys_llseek_args *uap; 47143412Snewton{ 47243412Snewton struct lseek_args ap; 47343412Snewton 474107849Salfred ap.fd = uap->fd; 47543412Snewton 47643412Snewton#if BYTE_ORDER == BIG_ENDIAN 477107849Salfred ap.offset = (((u_int64_t) uap->offset1) << 32) | 478107849Salfred uap->offset2; 47943412Snewton#else 480107849Salfred ap.offset = (((u_int64_t) uap->offset2) << 32) | 481107849Salfred uap->offset1; 48243412Snewton#endif 483107849Salfred ap.whence = uap->whence; 48443412Snewton 485225617Skmacy return sys_lseek(td, &ap); 48643412Snewton} 48743412Snewton 48843412Snewtonint 48983366Sjuliansvr4_sys_access(td, uap) 490193014Sdelphij struct thread *td; 49143412Snewton struct svr4_sys_access_args *uap; 49243412Snewton{ 493141486Sjhb char *newpath; 494141486Sjhb int error; 49543412Snewton 496141486Sjhb CHECKALTEXIST(td, uap->path, &newpath); 497227691Sed error = kern_access(td, newpath, UIO_SYSSPACE, uap->amode); 498141486Sjhb free(newpath, M_TEMP); 499141486Sjhb return (error); 50043412Snewton} 50143412Snewton 50243412Snewton#if defined(NOTYET) 50343412Snewtonint 50483366Sjuliansvr4_sys_pread(td, uap) 505193014Sdelphij struct thread *td; 50643412Snewton struct svr4_sys_pread_args *uap; 50743412Snewton{ 50843412Snewton struct pread_args pra; 50943412Snewton 51043412Snewton /* 51143412Snewton * Just translate the args structure and call the NetBSD 51243412Snewton * pread(2) system call (offset type is 64-bit in NetBSD). 51343412Snewton */ 514107849Salfred pra.fd = uap->fd; 515107849Salfred pra.buf = uap->buf; 516107849Salfred pra.nbyte = uap->nbyte; 517107849Salfred pra.offset = uap->off; 51843412Snewton 51983366Sjulian return pread(td, &pra); 52043412Snewton} 52143412Snewton#endif 52243412Snewton 52343412Snewton#if defined(NOTYET) 52443412Snewtonint 52583366Sjuliansvr4_sys_pread64(td, v, retval) 526193014Sdelphij struct thread *td; 52743412Snewton void *v; 52843412Snewton register_t *retval; 52943412Snewton{ 53043412Snewton 53143412Snewton struct svr4_sys_pread64_args *uap = v; 53243412Snewton struct sys_pread_args pra; 53343412Snewton 53443412Snewton /* 53543412Snewton * Just translate the args structure and call the NetBSD 53643412Snewton * pread(2) system call (offset type is 64-bit in NetBSD). 53743412Snewton */ 538107849Salfred pra.fd = uap->fd; 539107849Salfred pra.buf = uap->buf; 540107849Salfred pra.nbyte = uap->nbyte; 541107849Salfred pra.offset = uap->off; 54243412Snewton 54383366Sjulian return (sys_pread(td, &pra, retval)); 54443412Snewton} 54543412Snewton#endif /* NOTYET */ 54643412Snewton 54743412Snewton#if defined(NOTYET) 54843412Snewtonint 54983366Sjuliansvr4_sys_pwrite(td, uap) 550193014Sdelphij struct thread *td; 55143412Snewton struct svr4_sys_pwrite_args *uap; 55243412Snewton{ 55343412Snewton struct pwrite_args pwa; 55443412Snewton 55543412Snewton /* 55643412Snewton * Just translate the args structure and call the NetBSD 55743412Snewton * pwrite(2) system call (offset type is 64-bit in NetBSD). 55843412Snewton */ 559107849Salfred pwa.fd = uap->fd; 560107849Salfred pwa.buf = uap->buf; 561107849Salfred pwa.nbyte = uap->nbyte; 562107849Salfred pwa.offset = uap->off; 56343412Snewton 56483366Sjulian return pwrite(td, &pwa); 56543412Snewton} 56643412Snewton#endif 56743412Snewton 56843412Snewton#if defined(NOTYET) 56943412Snewtonint 57083366Sjuliansvr4_sys_pwrite64(td, v, retval) 571193014Sdelphij struct thread *td; 57243412Snewton void *v; 57343412Snewton register_t *retval; 57443412Snewton{ 57543412Snewton struct svr4_sys_pwrite64_args *uap = v; 57643412Snewton struct sys_pwrite_args pwa; 57743412Snewton 57843412Snewton /* 57943412Snewton * Just translate the args structure and call the NetBSD 58043412Snewton * pwrite(2) system call (offset type is 64-bit in NetBSD). 58143412Snewton */ 582107849Salfred pwa.fd = uap->fd; 583107849Salfred pwa.buf = uap->buf; 584107849Salfred pwa.nbyte = uap->nbyte; 585107849Salfred pwa.offset = uap->off; 58643412Snewton 58783366Sjulian return (sys_pwrite(td, &pwa, retval)); 58843412Snewton} 58943412Snewton#endif /* NOTYET */ 59043412Snewton 59143412Snewtonint 59283366Sjuliansvr4_sys_fcntl(td, uap) 593193014Sdelphij struct thread *td; 59443412Snewton struct svr4_sys_fcntl_args *uap; 59543412Snewton{ 596134266Sjhb int cmd, error, *retval; 59743412Snewton 59883366Sjulian retval = td->td_retval; 59943412Snewton 600134266Sjhb cmd = svr4_to_bsd_cmd(uap->cmd); 60143412Snewton 602134266Sjhb switch (cmd) { 60343412Snewton case F_DUPFD: 604177314Santoine case F_DUP2FD: 60543412Snewton case F_GETFD: 60643412Snewton case F_SETFD: 607134266Sjhb return (kern_fcntl(td, uap->fd, cmd, (intptr_t)uap->arg)); 60843412Snewton 60943412Snewton case F_GETFL: 610134266Sjhb error = kern_fcntl(td, uap->fd, cmd, (intptr_t)uap->arg); 61143412Snewton if (error) 612134266Sjhb return (error); 61343412Snewton *retval = bsd_to_svr4_flags(*retval); 614134266Sjhb return (error); 61543412Snewton 61643412Snewton case F_SETFL: 61743412Snewton { 61843412Snewton /* 61943412Snewton * we must save the O_ASYNC flag, as that is 62043412Snewton * handled by ioctl(_, I_SETSIG, _) emulation. 62143412Snewton */ 62243412Snewton int flags; 62343412Snewton 624107849Salfred DPRINTF(("Setting flags %p\n", uap->arg)); 62543412Snewton 626134266Sjhb error = kern_fcntl(td, uap->fd, F_GETFL, 0); 627134266Sjhb if (error) 628134266Sjhb return (error); 62943412Snewton flags = *retval; 63043412Snewton flags &= O_ASYNC; 631107849Salfred flags |= svr4_to_bsd_flags((u_long) uap->arg); 632134266Sjhb return (kern_fcntl(td, uap->fd, F_SETFL, flags)); 63343412Snewton } 63443412Snewton 63543412Snewton case F_GETLK: 63643412Snewton case F_SETLK: 63743412Snewton case F_SETLKW: 63843412Snewton { 639134266Sjhb struct svr4_flock ifl; 640134266Sjhb struct flock fl; 64143412Snewton 642134266Sjhb error = copyin(uap->arg, &ifl, sizeof (ifl)); 64343412Snewton if (error) 644134266Sjhb return (error); 64543412Snewton 64643412Snewton svr4_to_bsd_flock(&ifl, &fl); 64743412Snewton 648134266Sjhb error = kern_fcntl(td, uap->fd, cmd, (intptr_t)&fl); 649134266Sjhb if (error || cmd != F_GETLK) 650134266Sjhb return (error); 65143412Snewton 65243412Snewton bsd_to_svr4_flock(&fl, &ifl); 65343412Snewton 654134266Sjhb return (copyout(&ifl, uap->arg, sizeof (ifl))); 65543412Snewton } 65643412Snewton case -1: 657107849Salfred switch (uap->cmd) { 65843412Snewton case SVR4_F_FREESP: 65943412Snewton { 66043412Snewton struct svr4_flock ifl; 66143412Snewton struct flock fl; 66243412Snewton 663107849Salfred error = copyin(uap->arg, &ifl, 66443412Snewton sizeof ifl); 66543412Snewton if (error) 66643412Snewton return error; 66743412Snewton svr4_to_bsd_flock(&ifl, &fl); 668107849Salfred return fd_truncate(td, uap->fd, &fl); 66943412Snewton } 67043412Snewton 67143412Snewton case SVR4_F_GETLK64: 67243412Snewton case SVR4_F_SETLK64: 67343412Snewton case SVR4_F_SETLKW64: 67443412Snewton { 675134266Sjhb struct svr4_flock64 ifl; 676134266Sjhb struct flock fl; 67743412Snewton 678134266Sjhb switch (uap->cmd) { 679134266Sjhb case SVR4_F_GETLK64: 680134266Sjhb cmd = F_GETLK; 681134266Sjhb break; 682134266Sjhb case SVR4_F_SETLK64: 683134266Sjhb cmd = F_SETLK; 684134266Sjhb break; 685134266Sjhb case SVR4_F_SETLKW64: 686134266Sjhb cmd = F_SETLKW; 687134266Sjhb break; 688134266Sjhb } 689107849Salfred error = copyin(uap->arg, &ifl, 690134266Sjhb sizeof (ifl)); 69143412Snewton if (error) 692134266Sjhb return (error); 69343412Snewton 69443412Snewton svr4_to_bsd_flock64(&ifl, &fl); 69543412Snewton 696134266Sjhb error = kern_fcntl(td, uap->fd, cmd, 697134266Sjhb (intptr_t)&fl); 698134266Sjhb if (error || cmd != F_GETLK) 699134266Sjhb return (error); 70043412Snewton 70143412Snewton bsd_to_svr4_flock64(&fl, &ifl); 70243412Snewton 703134266Sjhb return (copyout(&ifl, uap->arg, 704134266Sjhb sizeof (ifl))); 70543412Snewton } 70643412Snewton 70743412Snewton case SVR4_F_FREESP64: 70843412Snewton { 70943412Snewton struct svr4_flock64 ifl; 71043412Snewton struct flock fl; 71143412Snewton 712107849Salfred error = copyin(uap->arg, &ifl, 71343412Snewton sizeof ifl); 71443412Snewton if (error) 71543412Snewton return error; 71643412Snewton svr4_to_bsd_flock64(&ifl, &fl); 717107849Salfred return fd_truncate(td, uap->fd, &fl); 71843412Snewton } 71943412Snewton 72043412Snewton case SVR4_F_REVOKE: 721107849Salfred return fd_revoke(td, uap->fd); 72243412Snewton 72343412Snewton default: 72443412Snewton return ENOSYS; 72543412Snewton } 72643412Snewton 72743412Snewton default: 72843412Snewton return ENOSYS; 72943412Snewton } 73043412Snewton} 731