svr4_fcntl.c revision 102003
143412Snewton/* 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. 3049267Snewton * 3150477Speter * $FreeBSD: head/sys/compat/svr4/svr4_fcntl.c 102003 2002-08-17 02:36:16Z rwatson $ 3243412Snewton */ 33101709Srwatson 34101709Srwatson#include "opt_mac.h" 35101709Srwatson 3643412Snewton#include <sys/param.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> 42101709Srwatson#include <sys/mac.h> 4343412Snewton#include <sys/mount.h> 4476166Smarkm#include <sys/mutex.h> 4576166Smarkm#include <sys/namei.h> 4676166Smarkm#include <sys/proc.h> 4776166Smarkm#include <sys/stat.h> 4876166Smarkm#include <sys/unistd.h> 4943412Snewton#include <sys/vnode.h> 5043412Snewton 5143412Snewton#include <sys/sysproto.h> 5243412Snewton 5365302Sobrien#include <compat/svr4/svr4.h> 5465302Sobrien#include <compat/svr4/svr4_types.h> 5565302Sobrien#include <compat/svr4/svr4_signal.h> 5665302Sobrien#include <compat/svr4/svr4_proto.h> 5765302Sobrien#include <compat/svr4/svr4_util.h> 5865302Sobrien#include <compat/svr4/svr4_fcntl.h> 5943412Snewton 6092761Salfredstatic int svr4_to_bsd_flags(int); 6192761Salfredstatic u_long svr4_to_bsd_cmd(u_long); 6292761Salfredstatic int fd_revoke(struct thread *, int); 6392761Salfredstatic int fd_truncate(struct thread *, int, struct flock *); 6492761Salfredstatic int bsd_to_svr4_flags(int); 6592761Salfredstatic void bsd_to_svr4_flock(struct flock *, struct svr4_flock *); 6692761Salfredstatic void svr4_to_bsd_flock(struct svr4_flock *, struct flock *); 6792761Salfredstatic void bsd_to_svr4_flock64(struct flock *, struct svr4_flock64 *); 6892761Salfredstatic void svr4_to_bsd_flock64(struct svr4_flock64 *, struct flock *); 6943412Snewton 7043412Snewtonstatic u_long 7143412Snewtonsvr4_to_bsd_cmd(cmd) 7243412Snewton u_long cmd; 7343412Snewton{ 7443412Snewton switch (cmd) { 7543412Snewton case SVR4_F_DUPFD: 7643412Snewton return F_DUPFD; 7743412Snewton case SVR4_F_GETFD: 7843412Snewton return F_GETFD; 7943412Snewton case SVR4_F_SETFD: 8043412Snewton return F_SETFD; 8143412Snewton case SVR4_F_GETFL: 8243412Snewton return F_GETFL; 8343412Snewton case SVR4_F_SETFL: 8443412Snewton return F_SETFL; 8543412Snewton case SVR4_F_GETLK: 8643412Snewton return F_GETLK; 8743412Snewton case SVR4_F_SETLK: 8843412Snewton return F_SETLK; 8943412Snewton case SVR4_F_SETLKW: 9043412Snewton return F_SETLKW; 9143412Snewton default: 9243412Snewton return -1; 9343412Snewton } 9443412Snewton} 9543412Snewton 9643412Snewtonstatic int 9743412Snewtonsvr4_to_bsd_flags(l) 9843412Snewton int l; 9943412Snewton{ 10043412Snewton int r = 0; 10143412Snewton r |= (l & SVR4_O_RDONLY) ? O_RDONLY : 0; 10243412Snewton r |= (l & SVR4_O_WRONLY) ? O_WRONLY : 0; 10343412Snewton r |= (l & SVR4_O_RDWR) ? O_RDWR : 0; 10443412Snewton r |= (l & SVR4_O_NDELAY) ? O_NONBLOCK : 0; 10543412Snewton r |= (l & SVR4_O_APPEND) ? O_APPEND : 0; 10643412Snewton r |= (l & SVR4_O_SYNC) ? O_FSYNC : 0; 10743412Snewton r |= (l & SVR4_O_NONBLOCK) ? O_NONBLOCK : 0; 10843412Snewton r |= (l & SVR4_O_PRIV) ? O_EXLOCK : 0; 10943412Snewton r |= (l & SVR4_O_CREAT) ? O_CREAT : 0; 11043412Snewton r |= (l & SVR4_O_TRUNC) ? O_TRUNC : 0; 11143412Snewton r |= (l & SVR4_O_EXCL) ? O_EXCL : 0; 11243412Snewton r |= (l & SVR4_O_NOCTTY) ? O_NOCTTY : 0; 11343412Snewton return r; 11443412Snewton} 11543412Snewton 11643412Snewtonstatic int 11743412Snewtonbsd_to_svr4_flags(l) 11843412Snewton int l; 11943412Snewton{ 12043412Snewton int r = 0; 12143412Snewton r |= (l & O_RDONLY) ? SVR4_O_RDONLY : 0; 12243412Snewton r |= (l & O_WRONLY) ? SVR4_O_WRONLY : 0; 12343412Snewton r |= (l & O_RDWR) ? SVR4_O_RDWR : 0; 12443412Snewton r |= (l & O_NDELAY) ? SVR4_O_NONBLOCK : 0; 12543412Snewton r |= (l & O_APPEND) ? SVR4_O_APPEND : 0; 12643412Snewton r |= (l & O_FSYNC) ? SVR4_O_SYNC : 0; 12743412Snewton r |= (l & O_NONBLOCK) ? SVR4_O_NONBLOCK : 0; 12843412Snewton r |= (l & O_EXLOCK) ? SVR4_O_PRIV : 0; 12943412Snewton r |= (l & O_CREAT) ? SVR4_O_CREAT : 0; 13043412Snewton r |= (l & O_TRUNC) ? SVR4_O_TRUNC : 0; 13143412Snewton r |= (l & O_EXCL) ? SVR4_O_EXCL : 0; 13243412Snewton r |= (l & O_NOCTTY) ? SVR4_O_NOCTTY : 0; 13343412Snewton return r; 13443412Snewton} 13543412Snewton 13643412Snewton 13743412Snewtonstatic void 13843412Snewtonbsd_to_svr4_flock(iflp, oflp) 13943412Snewton struct flock *iflp; 14043412Snewton struct svr4_flock *oflp; 14143412Snewton{ 14243412Snewton switch (iflp->l_type) { 14343412Snewton case F_RDLCK: 14443412Snewton oflp->l_type = SVR4_F_RDLCK; 14543412Snewton break; 14643412Snewton case F_WRLCK: 14743412Snewton oflp->l_type = SVR4_F_WRLCK; 14843412Snewton break; 14943412Snewton case F_UNLCK: 15043412Snewton oflp->l_type = SVR4_F_UNLCK; 15143412Snewton break; 15243412Snewton default: 15343412Snewton oflp->l_type = -1; 15443412Snewton break; 15543412Snewton } 15643412Snewton 15743412Snewton oflp->l_whence = (short) iflp->l_whence; 15843412Snewton oflp->l_start = (svr4_off_t) iflp->l_start; 15943412Snewton oflp->l_len = (svr4_off_t) iflp->l_len; 16043412Snewton oflp->l_sysid = 0; 16143412Snewton oflp->l_pid = (svr4_pid_t) iflp->l_pid; 16243412Snewton} 16343412Snewton 16443412Snewton 16543412Snewtonstatic void 16643412Snewtonsvr4_to_bsd_flock(iflp, oflp) 16743412Snewton struct svr4_flock *iflp; 16843412Snewton struct flock *oflp; 16943412Snewton{ 17043412Snewton switch (iflp->l_type) { 17143412Snewton case SVR4_F_RDLCK: 17243412Snewton oflp->l_type = F_RDLCK; 17343412Snewton break; 17443412Snewton case SVR4_F_WRLCK: 17543412Snewton oflp->l_type = F_WRLCK; 17643412Snewton break; 17743412Snewton case SVR4_F_UNLCK: 17843412Snewton oflp->l_type = F_UNLCK; 17943412Snewton break; 18043412Snewton default: 18143412Snewton oflp->l_type = -1; 18243412Snewton break; 18343412Snewton } 18443412Snewton 18543412Snewton oflp->l_whence = iflp->l_whence; 18643412Snewton oflp->l_start = (off_t) iflp->l_start; 18743412Snewton oflp->l_len = (off_t) iflp->l_len; 18843412Snewton oflp->l_pid = (pid_t) iflp->l_pid; 18943412Snewton 19043412Snewton} 19143412Snewton 19243412Snewtonstatic void 19343412Snewtonbsd_to_svr4_flock64(iflp, oflp) 19443412Snewton struct flock *iflp; 19543412Snewton struct svr4_flock64 *oflp; 19643412Snewton{ 19743412Snewton switch (iflp->l_type) { 19843412Snewton case F_RDLCK: 19943412Snewton oflp->l_type = SVR4_F_RDLCK; 20043412Snewton break; 20143412Snewton case F_WRLCK: 20243412Snewton oflp->l_type = SVR4_F_WRLCK; 20343412Snewton break; 20443412Snewton case F_UNLCK: 20543412Snewton oflp->l_type = SVR4_F_UNLCK; 20643412Snewton break; 20743412Snewton default: 20843412Snewton oflp->l_type = -1; 20943412Snewton break; 21043412Snewton } 21143412Snewton 21243412Snewton oflp->l_whence = (short) iflp->l_whence; 21343412Snewton oflp->l_start = (svr4_off64_t) iflp->l_start; 21443412Snewton oflp->l_len = (svr4_off64_t) iflp->l_len; 21543412Snewton oflp->l_sysid = 0; 21643412Snewton oflp->l_pid = (svr4_pid_t) iflp->l_pid; 21743412Snewton} 21843412Snewton 21943412Snewton 22043412Snewtonstatic void 22143412Snewtonsvr4_to_bsd_flock64(iflp, oflp) 22243412Snewton struct svr4_flock64 *iflp; 22343412Snewton struct flock *oflp; 22443412Snewton{ 22543412Snewton switch (iflp->l_type) { 22643412Snewton case SVR4_F_RDLCK: 22743412Snewton oflp->l_type = F_RDLCK; 22843412Snewton break; 22943412Snewton case SVR4_F_WRLCK: 23043412Snewton oflp->l_type = F_WRLCK; 23143412Snewton break; 23243412Snewton case SVR4_F_UNLCK: 23343412Snewton oflp->l_type = F_UNLCK; 23443412Snewton break; 23543412Snewton default: 23643412Snewton oflp->l_type = -1; 23743412Snewton break; 23843412Snewton } 23943412Snewton 24043412Snewton oflp->l_whence = iflp->l_whence; 24143412Snewton oflp->l_start = (off_t) iflp->l_start; 24243412Snewton oflp->l_len = (off_t) iflp->l_len; 24343412Snewton oflp->l_pid = (pid_t) iflp->l_pid; 24443412Snewton 24543412Snewton} 24643412Snewton 24743412Snewton 24843412Snewtonstatic int 24983366Sjulianfd_revoke(td, fd) 25083366Sjulian struct thread *td; 25143412Snewton int fd; 25243412Snewton{ 25343412Snewton struct vnode *vp; 25462976Smckusick struct mount *mp; 25543412Snewton struct vattr vattr; 25643412Snewton int error, *retval; 25743412Snewton 25883366Sjulian retval = td->td_retval; 25989319Salfred if ((error = fgetvp(td, fd, &vp)) != 0) 26089319Salfred return (error); 26143412Snewton 26243412Snewton if (vp->v_type != VCHR && vp->v_type != VBLK) { 26343412Snewton error = EINVAL; 26443412Snewton goto out; 26543412Snewton } 26643412Snewton 267101709Srwatson#ifdef MAC 268101709Srwatson vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 269101709Srwatson error = mac_check_vnode_revoke(td->td_ucred, vp); 270101709Srwatson VOP_UNLOCK(vp, 0, td); 271101709Srwatson if (error) 272101709Srwatson goto out; 273101709Srwatson#endif 274101709Srwatson 27591406Sjhb if ((error = VOP_GETATTR(vp, &vattr, td->td_ucred, td)) != 0) 27643412Snewton goto out; 27743412Snewton 27891406Sjhb if (td->td_ucred->cr_uid != vattr.va_uid && 27993593Sjhb (error = suser(td)) != 0) 28043412Snewton goto out; 28143412Snewton 28262976Smckusick if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) 28362976Smckusick goto out; 28450405Sphk if (vcount(vp) > 1) 28543412Snewton VOP_REVOKE(vp, REVOKEALL); 28662976Smckusick vn_finished_write(mp); 28743412Snewtonout: 28843412Snewton vrele(vp); 28943412Snewton return error; 29043412Snewton} 29143412Snewton 29243412Snewton 29343412Snewtonstatic int 29483366Sjulianfd_truncate(td, fd, flp) 29583366Sjulian struct thread *td; 29643412Snewton int fd; 29743412Snewton struct flock *flp; 29843412Snewton{ 29943412Snewton off_t start, length; 30089534Salfred struct file *fp; 30143412Snewton struct vnode *vp; 30243412Snewton struct vattr vattr; 30343412Snewton int error, *retval; 30443412Snewton struct ftruncate_args ft; 30543412Snewton 30683366Sjulian retval = td->td_retval; 30743412Snewton 30843412Snewton /* 30943412Snewton * We only support truncating the file. 31043412Snewton */ 31189534Salfred if ((error = fget(td, fd, &fp)) != 0) 31289319Salfred return (error); 31343412Snewton 31489534Salfred vp = (struct vnode *) fp->f_data; 31589534Salfred 31689534Salfred if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) { 31789534Salfred fdrop(fp, td); 31843412Snewton return ESPIPE; 31989306Salfred } 32043412Snewton 32191406Sjhb if ((error = VOP_GETATTR(vp, &vattr, td->td_ucred, td)) != 0) { 32289534Salfred fdrop(fp, td); 32343412Snewton return error; 32489306Salfred } 32543412Snewton 32643412Snewton length = vattr.va_size; 32743412Snewton 32843412Snewton switch (flp->l_whence) { 32943412Snewton case SEEK_CUR: 33043412Snewton start = fp->f_offset + flp->l_start; 33143412Snewton break; 33243412Snewton 33343412Snewton case SEEK_END: 33443412Snewton start = flp->l_start + length; 33543412Snewton break; 33643412Snewton 33743412Snewton case SEEK_SET: 33843412Snewton start = flp->l_start; 33943412Snewton break; 34043412Snewton 34143412Snewton default: 34289534Salfred fdrop(fp, td); 34343412Snewton return EINVAL; 34443412Snewton } 34543412Snewton 34643412Snewton if (start + flp->l_len < length) { 34743412Snewton /* We don't support free'ing in the middle of the file */ 34889534Salfred fdrop(fp, td); 34943412Snewton return EINVAL; 35043412Snewton } 35143412Snewton 35243412Snewton SCARG(&ft, fd) = fd; 35343412Snewton SCARG(&ft, length) = start; 35443412Snewton 35589306Salfred error = ftruncate(td, &ft); 35689306Salfred 35789534Salfred fdrop(fp, td); 35889306Salfred return (error); 35943412Snewton} 36043412Snewton 36143412Snewtonint 36283366Sjuliansvr4_sys_open(td, uap) 36383366Sjulian register struct thread *td; 36443412Snewton struct svr4_sys_open_args *uap; 36543412Snewton{ 36683366Sjulian struct proc *p = td->td_proc; 36743412Snewton int error, retval; 36843412Snewton struct open_args cup; 36943412Snewton 37043412Snewton caddr_t sg = stackgap_init(); 37183366Sjulian CHECKALTEXIST(td, &sg, SCARG(uap, path)); 37243412Snewton 37343412Snewton (&cup)->path = uap->path; 37443412Snewton (&cup)->flags = svr4_to_bsd_flags(uap->flags); 37543412Snewton (&cup)->mode = uap->mode; 37683366Sjulian error = open(td, &cup); 37743412Snewton 37843412Snewton if (error) { 37943412Snewton /* uprintf("svr4_open(%s, 0x%0x, 0%o): %d\n", uap->path, 38043412Snewton uap->flags, uap->mode, error);*/ 38143412Snewton return error; 38243412Snewton } 38343412Snewton 38483366Sjulian retval = td->td_retval[0]; 38543412Snewton 38671454Sjhb PROC_LOCK(p); 38743412Snewton if (!(SCARG(&cup, flags) & O_NOCTTY) && SESS_LEADER(p) && 38883366Sjulian !(td->td_proc->p_flag & P_CONTROLT)) { 38943412Snewton#if defined(NOTYET) 39089306Salfred struct file *fp; 39143412Snewton 39289319Salfred error = fget(td, retval, &fp); 39371454Sjhb PROC_UNLOCK(p); 39489306Salfred /* 39589306Salfred * we may have lost a race the above open() and 39689306Salfred * another thread issuing a close() 39789306Salfred */ 39889319Salfred if (error) 39989306Salfred return (EBADF); /* XXX: correct errno? */ 40043412Snewton /* ignore any error, just give it a try */ 40143412Snewton if (fp->f_type == DTYPE_VNODE) 402102003Srwatson fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td->td_ucred, 403102003Srwatson td); 40489306Salfred fdrop(fp, td); 40589306Salfred } else { 40671454Sjhb PROC_UNLOCK(p); 40789306Salfred } 40871454Sjhb#else 40971454Sjhb } 41071454Sjhb PROC_UNLOCK(p); 41143412Snewton#endif 41243412Snewton return error; 41343412Snewton} 41443412Snewton 41543412Snewtonint 41683366Sjuliansvr4_sys_open64(td, uap) 41783366Sjulian register struct thread *td; 41843412Snewton struct svr4_sys_open64_args *uap; 41943412Snewton{ 42083366Sjulian return svr4_sys_open(td, (struct svr4_sys_open_args *)uap); 42143412Snewton} 42243412Snewton 42343412Snewtonint 42483366Sjuliansvr4_sys_creat(td, uap) 42583366Sjulian register struct thread *td; 42643412Snewton struct svr4_sys_creat_args *uap; 42743412Snewton{ 42843412Snewton struct open_args cup; 42943412Snewton 43043412Snewton caddr_t sg = stackgap_init(); 43183366Sjulian CHECKALTEXIST(td, &sg, SCARG(uap, path)); 43243412Snewton 43343412Snewton SCARG(&cup, path) = SCARG(uap, path); 43443412Snewton SCARG(&cup, mode) = SCARG(uap, mode); 43543412Snewton SCARG(&cup, flags) = O_WRONLY | O_CREAT | O_TRUNC; 43643412Snewton 43783366Sjulian return open(td, &cup); 43843412Snewton} 43943412Snewton 44043412Snewtonint 44183366Sjuliansvr4_sys_creat64(td, uap) 44283366Sjulian register struct thread *td; 44343412Snewton struct svr4_sys_creat64_args *uap; 44443412Snewton{ 44583366Sjulian return svr4_sys_creat(td, (struct svr4_sys_creat_args *)uap); 44643412Snewton} 44743412Snewton 44843412Snewtonint 44983366Sjuliansvr4_sys_llseek(td, uap) 45083366Sjulian register struct thread *td; 45171454Sjhb struct svr4_sys_llseek_args *uap; 45243412Snewton{ 45343412Snewton struct lseek_args ap; 45443412Snewton 45543412Snewton SCARG(&ap, fd) = SCARG(uap, fd); 45643412Snewton 45743412Snewton#if BYTE_ORDER == BIG_ENDIAN 45871454Sjhb SCARG(&ap, offset) = (((u_int64_t) SCARG(uap, offset1)) << 32) | 45943412Snewton SCARG(uap, offset2); 46043412Snewton#else 46171454Sjhb SCARG(&ap, offset) = (((u_int64_t) SCARG(uap, offset2)) << 32) | 46243412Snewton SCARG(uap, offset1); 46343412Snewton#endif 46443412Snewton SCARG(&ap, whence) = SCARG(uap, whence); 46543412Snewton 46683366Sjulian return lseek(td, &ap); 46743412Snewton} 46843412Snewton 46943412Snewtonint 47083366Sjuliansvr4_sys_access(td, uap) 47183366Sjulian register struct thread *td; 47243412Snewton struct svr4_sys_access_args *uap; 47343412Snewton{ 47443412Snewton struct access_args cup; 47543412Snewton int *retval; 47643412Snewton 47743412Snewton caddr_t sg = stackgap_init(); 47883366Sjulian CHECKALTEXIST(td, &sg, SCARG(uap, path)); 47943412Snewton 48083366Sjulian retval = td->td_retval; 48143412Snewton 48243412Snewton SCARG(&cup, path) = SCARG(uap, path); 48343412Snewton SCARG(&cup, flags) = SCARG(uap, flags); 48443412Snewton 48583366Sjulian return access(td, &cup); 48643412Snewton} 48743412Snewton 48843412Snewton#if defined(NOTYET) 48943412Snewtonint 49083366Sjuliansvr4_sys_pread(td, uap) 49183366Sjulian register struct thread *td; 49243412Snewton struct svr4_sys_pread_args *uap; 49343412Snewton{ 49443412Snewton struct pread_args pra; 49543412Snewton 49643412Snewton /* 49743412Snewton * Just translate the args structure and call the NetBSD 49843412Snewton * pread(2) system call (offset type is 64-bit in NetBSD). 49943412Snewton */ 50043412Snewton SCARG(&pra, fd) = SCARG(uap, fd); 50143412Snewton SCARG(&pra, buf) = SCARG(uap, buf); 50243412Snewton SCARG(&pra, nbyte) = SCARG(uap, nbyte); 50343412Snewton SCARG(&pra, offset) = SCARG(uap, off); 50443412Snewton 50583366Sjulian return pread(td, &pra); 50643412Snewton} 50743412Snewton#endif 50843412Snewton 50943412Snewton#if defined(NOTYET) 51043412Snewtonint 51183366Sjuliansvr4_sys_pread64(td, v, retval) 51283366Sjulian register struct thread *td; 51343412Snewton void *v; 51443412Snewton register_t *retval; 51543412Snewton{ 51643412Snewton 51743412Snewton struct svr4_sys_pread64_args *uap = v; 51843412Snewton struct sys_pread_args pra; 51943412Snewton 52043412Snewton /* 52143412Snewton * Just translate the args structure and call the NetBSD 52243412Snewton * pread(2) system call (offset type is 64-bit in NetBSD). 52343412Snewton */ 52443412Snewton SCARG(&pra, fd) = SCARG(uap, fd); 52543412Snewton SCARG(&pra, buf) = SCARG(uap, buf); 52643412Snewton SCARG(&pra, nbyte) = SCARG(uap, nbyte); 52743412Snewton SCARG(&pra, offset) = SCARG(uap, off); 52843412Snewton 52983366Sjulian return (sys_pread(td, &pra, retval)); 53043412Snewton} 53143412Snewton#endif /* NOTYET */ 53243412Snewton 53343412Snewton#if defined(NOTYET) 53443412Snewtonint 53583366Sjuliansvr4_sys_pwrite(td, uap) 53683366Sjulian register struct thread *td; 53743412Snewton struct svr4_sys_pwrite_args *uap; 53843412Snewton{ 53943412Snewton struct pwrite_args pwa; 54043412Snewton 54143412Snewton /* 54243412Snewton * Just translate the args structure and call the NetBSD 54343412Snewton * pwrite(2) system call (offset type is 64-bit in NetBSD). 54443412Snewton */ 54543412Snewton SCARG(&pwa, fd) = SCARG(uap, fd); 54643412Snewton SCARG(&pwa, buf) = SCARG(uap, buf); 54743412Snewton SCARG(&pwa, nbyte) = SCARG(uap, nbyte); 54843412Snewton SCARG(&pwa, offset) = SCARG(uap, off); 54943412Snewton 55083366Sjulian return pwrite(td, &pwa); 55143412Snewton} 55243412Snewton#endif 55343412Snewton 55443412Snewton#if defined(NOTYET) 55543412Snewtonint 55683366Sjuliansvr4_sys_pwrite64(td, v, retval) 55783366Sjulian register struct thread *td; 55843412Snewton void *v; 55943412Snewton register_t *retval; 56043412Snewton{ 56143412Snewton struct svr4_sys_pwrite64_args *uap = v; 56243412Snewton struct sys_pwrite_args pwa; 56343412Snewton 56443412Snewton /* 56543412Snewton * Just translate the args structure and call the NetBSD 56643412Snewton * pwrite(2) system call (offset type is 64-bit in NetBSD). 56743412Snewton */ 56843412Snewton SCARG(&pwa, fd) = SCARG(uap, fd); 56943412Snewton SCARG(&pwa, buf) = SCARG(uap, buf); 57043412Snewton SCARG(&pwa, nbyte) = SCARG(uap, nbyte); 57143412Snewton SCARG(&pwa, offset) = SCARG(uap, off); 57243412Snewton 57383366Sjulian return (sys_pwrite(td, &pwa, retval)); 57443412Snewton} 57543412Snewton#endif /* NOTYET */ 57643412Snewton 57743412Snewtonint 57883366Sjuliansvr4_sys_fcntl(td, uap) 57983366Sjulian register struct thread *td; 58043412Snewton struct svr4_sys_fcntl_args *uap; 58143412Snewton{ 58243412Snewton int error; 58343412Snewton struct fcntl_args fa; 58443412Snewton int *retval; 58543412Snewton 58683366Sjulian retval = td->td_retval; 58743412Snewton 58843412Snewton SCARG(&fa, fd) = SCARG(uap, fd); 58943412Snewton SCARG(&fa, cmd) = svr4_to_bsd_cmd(SCARG(uap, cmd)); 59043412Snewton 59143412Snewton switch (SCARG(&fa, cmd)) { 59243412Snewton case F_DUPFD: 59343412Snewton case F_GETFD: 59443412Snewton case F_SETFD: 59543412Snewton SCARG(&fa, arg) = (long) SCARG(uap, arg); 59683366Sjulian return fcntl(td, &fa); 59743412Snewton 59843412Snewton case F_GETFL: 59943412Snewton SCARG(&fa, arg) = (long) SCARG(uap, arg); 60083366Sjulian error = fcntl(td, &fa); 60143412Snewton if (error) 60243412Snewton return error; 60343412Snewton *retval = bsd_to_svr4_flags(*retval); 60443412Snewton return error; 60543412Snewton 60643412Snewton case F_SETFL: 60743412Snewton { 60843412Snewton /* 60943412Snewton * we must save the O_ASYNC flag, as that is 61043412Snewton * handled by ioctl(_, I_SETSIG, _) emulation. 61143412Snewton */ 61243412Snewton long cmd; 61343412Snewton int flags; 61443412Snewton 61580114Sassar DPRINTF(("Setting flags %p\n", SCARG(uap, arg))); 61643412Snewton cmd = SCARG(&fa, cmd); /* save it for a while */ 61743412Snewton 61843412Snewton SCARG(&fa, cmd) = F_GETFL; 61983366Sjulian if ((error = fcntl(td, &fa)) != 0) 62043412Snewton return error; 62143412Snewton flags = *retval; 62243412Snewton flags &= O_ASYNC; 62343412Snewton flags |= svr4_to_bsd_flags((u_long) SCARG(uap, arg)); 62443412Snewton SCARG(&fa, cmd) = cmd; 62543412Snewton SCARG(&fa, arg) = (long) flags; 62683366Sjulian return fcntl(td, &fa); 62743412Snewton } 62843412Snewton 62943412Snewton case F_GETLK: 63043412Snewton case F_SETLK: 63143412Snewton case F_SETLKW: 63243412Snewton { 63343412Snewton struct svr4_flock ifl; 63443412Snewton struct flock *flp, fl; 63543412Snewton caddr_t sg = stackgap_init(); 63643412Snewton 63743412Snewton flp = stackgap_alloc(&sg, sizeof(struct flock)); 63843412Snewton SCARG(&fa, arg) = (long) flp; 63943412Snewton 64043412Snewton error = copyin(SCARG(uap, arg), &ifl, sizeof ifl); 64143412Snewton if (error) 64243412Snewton return error; 64343412Snewton 64443412Snewton svr4_to_bsd_flock(&ifl, &fl); 64543412Snewton 64643412Snewton error = copyout(&fl, flp, sizeof fl); 64743412Snewton if (error) 64843412Snewton return error; 64943412Snewton 65083366Sjulian error = fcntl(td, &fa); 65143412Snewton if (error || SCARG(&fa, cmd) != F_GETLK) 65243412Snewton return error; 65343412Snewton 65443412Snewton error = copyin(flp, &fl, sizeof fl); 65543412Snewton if (error) 65643412Snewton return error; 65743412Snewton 65843412Snewton bsd_to_svr4_flock(&fl, &ifl); 65943412Snewton 66043412Snewton return copyout(&ifl, SCARG(uap, arg), sizeof ifl); 66143412Snewton } 66243412Snewton case -1: 66343412Snewton switch (SCARG(uap, cmd)) { 66443412Snewton case SVR4_F_DUP2FD: 66543412Snewton { 66643412Snewton struct dup2_args du; 66743412Snewton 66843412Snewton SCARG(&du, from) = SCARG(uap, fd); 66943412Snewton SCARG(&du, to) = (int)SCARG(uap, arg); 67083366Sjulian error = dup2(td, &du); 67143412Snewton if (error) 67243412Snewton return error; 67343412Snewton *retval = SCARG(&du, to); 67443412Snewton return 0; 67543412Snewton } 67643412Snewton 67743412Snewton case SVR4_F_FREESP: 67843412Snewton { 67943412Snewton struct svr4_flock ifl; 68043412Snewton struct flock fl; 68143412Snewton 68243412Snewton error = copyin(SCARG(uap, arg), &ifl, 68343412Snewton sizeof ifl); 68443412Snewton if (error) 68543412Snewton return error; 68643412Snewton svr4_to_bsd_flock(&ifl, &fl); 68783366Sjulian return fd_truncate(td, SCARG(uap, fd), &fl); 68843412Snewton } 68943412Snewton 69043412Snewton case SVR4_F_GETLK64: 69143412Snewton case SVR4_F_SETLK64: 69243412Snewton case SVR4_F_SETLKW64: 69343412Snewton { 69443412Snewton struct svr4_flock64 ifl; 69543412Snewton struct flock *flp, fl; 69643412Snewton caddr_t sg = stackgap_init(); 69743412Snewton 69843412Snewton flp = stackgap_alloc(&sg, sizeof(struct flock)); 69943412Snewton SCARG(&fa, arg) = (long) flp; 70043412Snewton 70143412Snewton error = copyin(SCARG(uap, arg), &ifl, 70243412Snewton sizeof ifl); 70343412Snewton if (error) 70443412Snewton return error; 70543412Snewton 70643412Snewton svr4_to_bsd_flock64(&ifl, &fl); 70743412Snewton 70843412Snewton error = copyout(&fl, flp, sizeof fl); 70943412Snewton if (error) 71043412Snewton return error; 71143412Snewton 71283366Sjulian error = fcntl(td, &fa); 71343412Snewton if (error || SCARG(&fa, cmd) != F_GETLK) 71443412Snewton return error; 71543412Snewton 71643412Snewton error = copyin(flp, &fl, sizeof fl); 71743412Snewton if (error) 71843412Snewton return error; 71943412Snewton 72043412Snewton bsd_to_svr4_flock64(&fl, &ifl); 72143412Snewton 72243412Snewton return copyout(&ifl, SCARG(uap, arg), 72343412Snewton sizeof ifl); 72443412Snewton } 72543412Snewton 72643412Snewton case SVR4_F_FREESP64: 72743412Snewton { 72843412Snewton struct svr4_flock64 ifl; 72943412Snewton struct flock fl; 73043412Snewton 73143412Snewton error = copyin(SCARG(uap, arg), &ifl, 73243412Snewton sizeof ifl); 73343412Snewton if (error) 73443412Snewton return error; 73543412Snewton svr4_to_bsd_flock64(&ifl, &fl); 73683366Sjulian return fd_truncate(td, SCARG(uap, fd), &fl); 73743412Snewton } 73843412Snewton 73943412Snewton case SVR4_F_REVOKE: 74083366Sjulian return fd_revoke(td, SCARG(uap, fd)); 74143412Snewton 74243412Snewton default: 74343412Snewton return ENOSYS; 74443412Snewton } 74543412Snewton 74643412Snewton default: 74743412Snewton return ENOSYS; 74843412Snewton } 74943412Snewton} 750