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; 26243412Snewton int error, *retval; 26343412Snewton 26483366Sjulian retval = td->td_retval; 265224778Srwatson /* 266224778Srwatson * If we ever want to support Capsicum on SVR4 processes (unlikely) 267224778Srwatson * or FreeBSD grows a native frevoke() (more likely), we will need a 268224778Srwatson * CAP_REVOKE here. 269224778Srwatson * 270224778Srwatson * In the meantime, use CAP_MASK_VALID: if a SVR4 process wants to 271224778Srwatson * do an frevoke(), it needs to do it on either a regular file 272224778Srwatson * descriptor or a fully-privileged capability (which is effectively 273224778Srwatson * the same as a non-capability-restricted file descriptor). 274224778Srwatson */ 275224778Srwatson if ((error = fgetvp(td, fd, CAP_MASK_VALID, &vp)) != 0) 27689319Salfred return (error); 27743412Snewton 27843412Snewton if (vp->v_type != VCHR && vp->v_type != VBLK) { 27943412Snewton error = EINVAL; 28043412Snewton goto out; 28143412Snewton } 28243412Snewton 283101709Srwatson#ifdef MAC 284175202Sattilio vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 285172930Srwatson error = mac_vnode_check_revoke(td->td_ucred, vp); 286175294Sattilio VOP_UNLOCK(vp, 0); 287101709Srwatson if (error) 288101709Srwatson goto out; 289101709Srwatson#endif 290101709Srwatson 291182371Sattilio if ((error = VOP_GETATTR(vp, &vattr, td->td_ucred)) != 0) 29243412Snewton goto out; 29343412Snewton 29491406Sjhb if (td->td_ucred->cr_uid != vattr.va_uid && 295170587Srwatson (error = priv_check(td, PRIV_VFS_ADMIN)) != 0) 29643412Snewton goto out; 29743412Snewton 29862976Smckusick if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 29962976Smckusick goto out; 30050405Sphk if (vcount(vp) > 1) 30143412Snewton VOP_REVOKE(vp, REVOKEALL); 30262976Smckusick vn_finished_write(mp); 30343412Snewtonout: 30443412Snewton vrele(vp); 30543412Snewton return error; 30643412Snewton} 30743412Snewton 30843412Snewton 30943412Snewtonstatic int 31083366Sjulianfd_truncate(td, fd, flp) 31183366Sjulian struct thread *td; 31243412Snewton int fd; 31343412Snewton struct flock *flp; 31443412Snewton{ 31543412Snewton off_t start, length; 31689534Salfred struct file *fp; 31743412Snewton struct vnode *vp; 31843412Snewton struct vattr vattr; 31943412Snewton int error, *retval; 32043412Snewton struct ftruncate_args ft; 32143412Snewton 32283366Sjulian retval = td->td_retval; 32343412Snewton 32443412Snewton /* 32543412Snewton * We only support truncating the file. 32643412Snewton */ 327224778Srwatson if ((error = fget(td, fd, CAP_FTRUNCATE, &fp)) != 0) 32889319Salfred return (error); 32943412Snewton 330116678Sphk vp = fp->f_vnode; 33189534Salfred 33289534Salfred if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) { 33389534Salfred fdrop(fp, td); 33443412Snewton return ESPIPE; 33589306Salfred } 33643412Snewton 337182371Sattilio if ((error = VOP_GETATTR(vp, &vattr, td->td_ucred)) != 0) { 33889534Salfred fdrop(fp, td); 33943412Snewton return error; 34089306Salfred } 34143412Snewton 34243412Snewton length = vattr.va_size; 34343412Snewton 34443412Snewton switch (flp->l_whence) { 34543412Snewton case SEEK_CUR: 34643412Snewton start = fp->f_offset + flp->l_start; 34743412Snewton break; 34843412Snewton 34943412Snewton case SEEK_END: 35043412Snewton start = flp->l_start + length; 35143412Snewton break; 35243412Snewton 35343412Snewton case SEEK_SET: 35443412Snewton start = flp->l_start; 35543412Snewton break; 35643412Snewton 35743412Snewton default: 35889534Salfred fdrop(fp, td); 35943412Snewton return EINVAL; 36043412Snewton } 36143412Snewton 36243412Snewton if (start + flp->l_len < length) { 36343412Snewton /* We don't support free'ing in the middle of the file */ 36489534Salfred fdrop(fp, td); 36543412Snewton return EINVAL; 36643412Snewton } 36743412Snewton 368107849Salfred ft.fd = fd; 369107849Salfred ft.length = start; 37043412Snewton 371225617Skmacy error = sys_ftruncate(td, &ft); 37289306Salfred 37389534Salfred fdrop(fp, td); 37489306Salfred return (error); 37543412Snewton} 37643412Snewton 37743412Snewtonint 37883366Sjuliansvr4_sys_open(td, uap) 379193014Sdelphij struct thread *td; 38043412Snewton struct svr4_sys_open_args *uap; 38143412Snewton{ 38283366Sjulian struct proc *p = td->td_proc; 383141486Sjhb char *newpath; 384141486Sjhb int bsd_flags, error, retval; 38543412Snewton 386141486Sjhb CHECKALTEXIST(td, uap->path, &newpath); 38743412Snewton 388141486Sjhb bsd_flags = svr4_to_bsd_flags(uap->flags); 389141486Sjhb error = kern_open(td, newpath, UIO_SYSSPACE, bsd_flags, uap->mode); 390141486Sjhb free(newpath, M_TEMP); 39143412Snewton 39243412Snewton if (error) { 393150663Srwatson /* uprintf("svr4_open(%s, 0x%0x, 0%o): %d\n", uap->path, 394150663Srwatson uap->flags, uap->mode, error);*/ 39543412Snewton return error; 39643412Snewton } 39743412Snewton 39883366Sjulian retval = td->td_retval[0]; 39943412Snewton 40071454Sjhb PROC_LOCK(p); 401141486Sjhb if (!(bsd_flags & O_NOCTTY) && SESS_LEADER(p) && 402141486Sjhb !(p->p_flag & P_CONTROLT)) { 40343412Snewton#if defined(NOTYET) 40489306Salfred struct file *fp; 40543412Snewton 406224778Srwatson error = fget(td, retval, CAP_IOCTL, &fp); 40771454Sjhb PROC_UNLOCK(p); 40889306Salfred /* 40989306Salfred * we may have lost a race the above open() and 41089306Salfred * another thread issuing a close() 41189306Salfred */ 41289319Salfred if (error) 41389306Salfred return (EBADF); /* XXX: correct errno? */ 41443412Snewton /* ignore any error, just give it a try */ 41543412Snewton if (fp->f_type == DTYPE_VNODE) 416102003Srwatson fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td->td_ucred, 417102003Srwatson td); 41889306Salfred fdrop(fp, td); 41989306Salfred } else { 42071454Sjhb PROC_UNLOCK(p); 42189306Salfred } 42271454Sjhb#else 42371454Sjhb } 42471454Sjhb PROC_UNLOCK(p); 42543412Snewton#endif 42643412Snewton return error; 42743412Snewton} 42843412Snewton 42943412Snewtonint 43083366Sjuliansvr4_sys_open64(td, uap) 431193014Sdelphij struct thread *td; 43243412Snewton struct svr4_sys_open64_args *uap; 43343412Snewton{ 43483366Sjulian return svr4_sys_open(td, (struct svr4_sys_open_args *)uap); 43543412Snewton} 43643412Snewton 43743412Snewtonint 43883366Sjuliansvr4_sys_creat(td, uap) 439193014Sdelphij struct thread *td; 44043412Snewton struct svr4_sys_creat_args *uap; 44143412Snewton{ 442141486Sjhb char *newpath; 443141486Sjhb int error; 44443412Snewton 445141486Sjhb CHECKALTEXIST(td, uap->path, &newpath); 44643412Snewton 447141486Sjhb error = kern_open(td, newpath, UIO_SYSSPACE, O_WRONLY | O_CREAT | 448141486Sjhb O_TRUNC, uap->mode); 449141486Sjhb free(newpath, M_TEMP); 450141486Sjhb return (error); 45143412Snewton} 45243412Snewton 45343412Snewtonint 45483366Sjuliansvr4_sys_creat64(td, uap) 455193014Sdelphij struct thread *td; 45643412Snewton struct svr4_sys_creat64_args *uap; 45743412Snewton{ 45883366Sjulian return svr4_sys_creat(td, (struct svr4_sys_creat_args *)uap); 45943412Snewton} 46043412Snewton 46143412Snewtonint 46283366Sjuliansvr4_sys_llseek(td, uap) 463193014Sdelphij struct thread *td; 46471454Sjhb struct svr4_sys_llseek_args *uap; 46543412Snewton{ 46643412Snewton struct lseek_args ap; 46743412Snewton 468107849Salfred ap.fd = uap->fd; 46943412Snewton 47043412Snewton#if BYTE_ORDER == BIG_ENDIAN 471107849Salfred ap.offset = (((u_int64_t) uap->offset1) << 32) | 472107849Salfred uap->offset2; 47343412Snewton#else 474107849Salfred ap.offset = (((u_int64_t) uap->offset2) << 32) | 475107849Salfred uap->offset1; 47643412Snewton#endif 477107849Salfred ap.whence = uap->whence; 47843412Snewton 479225617Skmacy return sys_lseek(td, &ap); 48043412Snewton} 48143412Snewton 48243412Snewtonint 48383366Sjuliansvr4_sys_access(td, uap) 484193014Sdelphij struct thread *td; 48543412Snewton struct svr4_sys_access_args *uap; 48643412Snewton{ 487141486Sjhb char *newpath; 488141486Sjhb int error; 48943412Snewton 490141486Sjhb CHECKALTEXIST(td, uap->path, &newpath); 491141486Sjhb error = kern_access(td, newpath, UIO_SYSSPACE, uap->flags); 492141486Sjhb free(newpath, M_TEMP); 493141486Sjhb return (error); 49443412Snewton} 49543412Snewton 49643412Snewton#if defined(NOTYET) 49743412Snewtonint 49883366Sjuliansvr4_sys_pread(td, uap) 499193014Sdelphij struct thread *td; 50043412Snewton struct svr4_sys_pread_args *uap; 50143412Snewton{ 50243412Snewton struct pread_args pra; 50343412Snewton 50443412Snewton /* 50543412Snewton * Just translate the args structure and call the NetBSD 50643412Snewton * pread(2) system call (offset type is 64-bit in NetBSD). 50743412Snewton */ 508107849Salfred pra.fd = uap->fd; 509107849Salfred pra.buf = uap->buf; 510107849Salfred pra.nbyte = uap->nbyte; 511107849Salfred pra.offset = uap->off; 51243412Snewton 51383366Sjulian return pread(td, &pra); 51443412Snewton} 51543412Snewton#endif 51643412Snewton 51743412Snewton#if defined(NOTYET) 51843412Snewtonint 51983366Sjuliansvr4_sys_pread64(td, v, retval) 520193014Sdelphij struct thread *td; 52143412Snewton void *v; 52243412Snewton register_t *retval; 52343412Snewton{ 52443412Snewton 52543412Snewton struct svr4_sys_pread64_args *uap = v; 52643412Snewton struct sys_pread_args pra; 52743412Snewton 52843412Snewton /* 52943412Snewton * Just translate the args structure and call the NetBSD 53043412Snewton * pread(2) system call (offset type is 64-bit in NetBSD). 53143412Snewton */ 532107849Salfred pra.fd = uap->fd; 533107849Salfred pra.buf = uap->buf; 534107849Salfred pra.nbyte = uap->nbyte; 535107849Salfred pra.offset = uap->off; 53643412Snewton 53783366Sjulian return (sys_pread(td, &pra, retval)); 53843412Snewton} 53943412Snewton#endif /* NOTYET */ 54043412Snewton 54143412Snewton#if defined(NOTYET) 54243412Snewtonint 54383366Sjuliansvr4_sys_pwrite(td, uap) 544193014Sdelphij struct thread *td; 54543412Snewton struct svr4_sys_pwrite_args *uap; 54643412Snewton{ 54743412Snewton struct pwrite_args pwa; 54843412Snewton 54943412Snewton /* 55043412Snewton * Just translate the args structure and call the NetBSD 55143412Snewton * pwrite(2) system call (offset type is 64-bit in NetBSD). 55243412Snewton */ 553107849Salfred pwa.fd = uap->fd; 554107849Salfred pwa.buf = uap->buf; 555107849Salfred pwa.nbyte = uap->nbyte; 556107849Salfred pwa.offset = uap->off; 55743412Snewton 55883366Sjulian return pwrite(td, &pwa); 55943412Snewton} 56043412Snewton#endif 56143412Snewton 56243412Snewton#if defined(NOTYET) 56343412Snewtonint 56483366Sjuliansvr4_sys_pwrite64(td, v, retval) 565193014Sdelphij struct thread *td; 56643412Snewton void *v; 56743412Snewton register_t *retval; 56843412Snewton{ 56943412Snewton struct svr4_sys_pwrite64_args *uap = v; 57043412Snewton struct sys_pwrite_args pwa; 57143412Snewton 57243412Snewton /* 57343412Snewton * Just translate the args structure and call the NetBSD 57443412Snewton * pwrite(2) system call (offset type is 64-bit in NetBSD). 57543412Snewton */ 576107849Salfred pwa.fd = uap->fd; 577107849Salfred pwa.buf = uap->buf; 578107849Salfred pwa.nbyte = uap->nbyte; 579107849Salfred pwa.offset = uap->off; 58043412Snewton 58183366Sjulian return (sys_pwrite(td, &pwa, retval)); 58243412Snewton} 58343412Snewton#endif /* NOTYET */ 58443412Snewton 58543412Snewtonint 58683366Sjuliansvr4_sys_fcntl(td, uap) 587193014Sdelphij struct thread *td; 58843412Snewton struct svr4_sys_fcntl_args *uap; 58943412Snewton{ 590134266Sjhb int cmd, error, *retval; 59143412Snewton 59283366Sjulian retval = td->td_retval; 59343412Snewton 594134266Sjhb cmd = svr4_to_bsd_cmd(uap->cmd); 59543412Snewton 596134266Sjhb switch (cmd) { 59743412Snewton case F_DUPFD: 598177314Santoine case F_DUP2FD: 59943412Snewton case F_GETFD: 60043412Snewton case F_SETFD: 601134266Sjhb return (kern_fcntl(td, uap->fd, cmd, (intptr_t)uap->arg)); 60243412Snewton 60343412Snewton case F_GETFL: 604134266Sjhb error = kern_fcntl(td, uap->fd, cmd, (intptr_t)uap->arg); 60543412Snewton if (error) 606134266Sjhb return (error); 60743412Snewton *retval = bsd_to_svr4_flags(*retval); 608134266Sjhb return (error); 60943412Snewton 61043412Snewton case F_SETFL: 61143412Snewton { 61243412Snewton /* 61343412Snewton * we must save the O_ASYNC flag, as that is 61443412Snewton * handled by ioctl(_, I_SETSIG, _) emulation. 61543412Snewton */ 61643412Snewton int flags; 61743412Snewton 618107849Salfred DPRINTF(("Setting flags %p\n", uap->arg)); 61943412Snewton 620134266Sjhb error = kern_fcntl(td, uap->fd, F_GETFL, 0); 621134266Sjhb if (error) 622134266Sjhb return (error); 62343412Snewton flags = *retval; 62443412Snewton flags &= O_ASYNC; 625107849Salfred flags |= svr4_to_bsd_flags((u_long) uap->arg); 626134266Sjhb return (kern_fcntl(td, uap->fd, F_SETFL, flags)); 62743412Snewton } 62843412Snewton 62943412Snewton case F_GETLK: 63043412Snewton case F_SETLK: 63143412Snewton case F_SETLKW: 63243412Snewton { 633134266Sjhb struct svr4_flock ifl; 634134266Sjhb struct flock fl; 63543412Snewton 636134266Sjhb error = copyin(uap->arg, &ifl, sizeof (ifl)); 63743412Snewton if (error) 638134266Sjhb return (error); 63943412Snewton 64043412Snewton svr4_to_bsd_flock(&ifl, &fl); 64143412Snewton 642134266Sjhb error = kern_fcntl(td, uap->fd, cmd, (intptr_t)&fl); 643134266Sjhb if (error || cmd != F_GETLK) 644134266Sjhb return (error); 64543412Snewton 64643412Snewton bsd_to_svr4_flock(&fl, &ifl); 64743412Snewton 648134266Sjhb return (copyout(&ifl, uap->arg, sizeof (ifl))); 64943412Snewton } 65043412Snewton case -1: 651107849Salfred switch (uap->cmd) { 65243412Snewton case SVR4_F_FREESP: 65343412Snewton { 65443412Snewton struct svr4_flock ifl; 65543412Snewton struct flock fl; 65643412Snewton 657107849Salfred error = copyin(uap->arg, &ifl, 65843412Snewton sizeof ifl); 65943412Snewton if (error) 66043412Snewton return error; 66143412Snewton svr4_to_bsd_flock(&ifl, &fl); 662107849Salfred return fd_truncate(td, uap->fd, &fl); 66343412Snewton } 66443412Snewton 66543412Snewton case SVR4_F_GETLK64: 66643412Snewton case SVR4_F_SETLK64: 66743412Snewton case SVR4_F_SETLKW64: 66843412Snewton { 669134266Sjhb struct svr4_flock64 ifl; 670134266Sjhb struct flock fl; 67143412Snewton 672134266Sjhb switch (uap->cmd) { 673134266Sjhb case SVR4_F_GETLK64: 674134266Sjhb cmd = F_GETLK; 675134266Sjhb break; 676134266Sjhb case SVR4_F_SETLK64: 677134266Sjhb cmd = F_SETLK; 678134266Sjhb break; 679134266Sjhb case SVR4_F_SETLKW64: 680134266Sjhb cmd = F_SETLKW; 681134266Sjhb break; 682134266Sjhb } 683107849Salfred error = copyin(uap->arg, &ifl, 684134266Sjhb sizeof (ifl)); 68543412Snewton if (error) 686134266Sjhb return (error); 68743412Snewton 68843412Snewton svr4_to_bsd_flock64(&ifl, &fl); 68943412Snewton 690134266Sjhb error = kern_fcntl(td, uap->fd, cmd, 691134266Sjhb (intptr_t)&fl); 692134266Sjhb if (error || cmd != F_GETLK) 693134266Sjhb return (error); 69443412Snewton 69543412Snewton bsd_to_svr4_flock64(&fl, &ifl); 69643412Snewton 697134266Sjhb return (copyout(&ifl, uap->arg, 698134266Sjhb sizeof (ifl))); 69943412Snewton } 70043412Snewton 70143412Snewton case SVR4_F_FREESP64: 70243412Snewton { 70343412Snewton struct svr4_flock64 ifl; 70443412Snewton struct flock fl; 70543412Snewton 706107849Salfred error = copyin(uap->arg, &ifl, 70743412Snewton sizeof ifl); 70843412Snewton if (error) 70943412Snewton return error; 71043412Snewton svr4_to_bsd_flock64(&ifl, &fl); 711107849Salfred return fd_truncate(td, uap->fd, &fl); 71243412Snewton } 71343412Snewton 71443412Snewton case SVR4_F_REVOKE: 715107849Salfred return fd_revoke(td, uap->fd); 71643412Snewton 71743412Snewton default: 71843412Snewton return ENOSYS; 71943412Snewton } 72043412Snewton 72143412Snewton default: 72243412Snewton return ENOSYS; 72343412Snewton } 72443412Snewton} 725