svr4_fcntl.c revision 46112
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. 3043412Snewton */ 3143412Snewton#include <sys/param.h> 3243412Snewton#include <sys/systm.h> 3343412Snewton#include <sys/namei.h> 3443412Snewton#include <sys/proc.h> 3543412Snewton#include <sys/file.h> 3643412Snewton#include <sys/stat.h> 3743412Snewton#include <sys/filedesc.h> 3843412Snewton/*#include <sys/ioctl.h>*/ 3943412Snewton#include <sys/kernel.h> 4043412Snewton#include <sys/mount.h> 4143412Snewton#include <sys/malloc.h> 4243412Snewton#include <sys/vnode.h> 4343412Snewton#include <sys/unistd.h> 4443412Snewton 4543412Snewton#include <sys/sysproto.h> 4643412Snewton 4743412Snewton#include <svr4/svr4.h> 4843412Snewton#include <svr4/svr4_types.h> 4943412Snewton#include <svr4/svr4_signal.h> 5043412Snewton#include <svr4/svr4_proto.h> 5143412Snewton#include <svr4/svr4_util.h> 5243412Snewton#include <svr4/svr4_fcntl.h> 5343412Snewton 5443412Snewtonstatic int svr4_to_bsd_flags __P((int)); 5543412Snewtonstatic u_long svr4_to_bsd_cmd __P((u_long)); 5643412Snewtonstatic int fd_revoke __P((struct proc *, int)); 5743412Snewtonstatic int fd_truncate __P((struct proc *, int, struct flock *)); 5843412Snewtonstatic int bsd_to_svr4_flags __P((int)); 5943412Snewtonstatic void bsd_to_svr4_flock __P((struct flock *, struct svr4_flock *)); 6043412Snewtonstatic void svr4_to_bsd_flock __P((struct svr4_flock *, struct flock *)); 6143412Snewtonstatic void bsd_to_svr4_flock64 __P((struct flock *, struct svr4_flock64 *)); 6243412Snewtonstatic void svr4_to_bsd_flock64 __P((struct svr4_flock64 *, struct flock *)); 6343412Snewton 6443412Snewtonstatic u_long 6543412Snewtonsvr4_to_bsd_cmd(cmd) 6643412Snewton u_long cmd; 6743412Snewton{ 6843412Snewton switch (cmd) { 6943412Snewton case SVR4_F_DUPFD: 7043412Snewton return F_DUPFD; 7143412Snewton case SVR4_F_GETFD: 7243412Snewton return F_GETFD; 7343412Snewton case SVR4_F_SETFD: 7443412Snewton return F_SETFD; 7543412Snewton case SVR4_F_GETFL: 7643412Snewton return F_GETFL; 7743412Snewton case SVR4_F_SETFL: 7843412Snewton return F_SETFL; 7943412Snewton case SVR4_F_GETLK: 8043412Snewton return F_GETLK; 8143412Snewton case SVR4_F_SETLK: 8243412Snewton return F_SETLK; 8343412Snewton case SVR4_F_SETLKW: 8443412Snewton return F_SETLKW; 8543412Snewton default: 8643412Snewton return -1; 8743412Snewton } 8843412Snewton} 8943412Snewton 9043412Snewtonstatic int 9143412Snewtonsvr4_to_bsd_flags(l) 9243412Snewton int l; 9343412Snewton{ 9443412Snewton int r = 0; 9543412Snewton r |= (l & SVR4_O_RDONLY) ? O_RDONLY : 0; 9643412Snewton r |= (l & SVR4_O_WRONLY) ? O_WRONLY : 0; 9743412Snewton r |= (l & SVR4_O_RDWR) ? O_RDWR : 0; 9843412Snewton r |= (l & SVR4_O_NDELAY) ? O_NONBLOCK : 0; 9943412Snewton r |= (l & SVR4_O_APPEND) ? O_APPEND : 0; 10043412Snewton r |= (l & SVR4_O_SYNC) ? O_FSYNC : 0; 10143412Snewton r |= (l & SVR4_O_NONBLOCK) ? O_NONBLOCK : 0; 10243412Snewton r |= (l & SVR4_O_PRIV) ? O_EXLOCK : 0; 10343412Snewton r |= (l & SVR4_O_CREAT) ? O_CREAT : 0; 10443412Snewton r |= (l & SVR4_O_TRUNC) ? O_TRUNC : 0; 10543412Snewton r |= (l & SVR4_O_EXCL) ? O_EXCL : 0; 10643412Snewton r |= (l & SVR4_O_NOCTTY) ? O_NOCTTY : 0; 10743412Snewton return r; 10843412Snewton} 10943412Snewton 11043412Snewtonstatic int 11143412Snewtonbsd_to_svr4_flags(l) 11243412Snewton int l; 11343412Snewton{ 11443412Snewton int r = 0; 11543412Snewton r |= (l & O_RDONLY) ? SVR4_O_RDONLY : 0; 11643412Snewton r |= (l & O_WRONLY) ? SVR4_O_WRONLY : 0; 11743412Snewton r |= (l & O_RDWR) ? SVR4_O_RDWR : 0; 11843412Snewton r |= (l & O_NDELAY) ? SVR4_O_NONBLOCK : 0; 11943412Snewton r |= (l & O_APPEND) ? SVR4_O_APPEND : 0; 12043412Snewton r |= (l & O_FSYNC) ? SVR4_O_SYNC : 0; 12143412Snewton r |= (l & O_NONBLOCK) ? SVR4_O_NONBLOCK : 0; 12243412Snewton r |= (l & O_EXLOCK) ? SVR4_O_PRIV : 0; 12343412Snewton r |= (l & O_CREAT) ? SVR4_O_CREAT : 0; 12443412Snewton r |= (l & O_TRUNC) ? SVR4_O_TRUNC : 0; 12543412Snewton r |= (l & O_EXCL) ? SVR4_O_EXCL : 0; 12643412Snewton r |= (l & O_NOCTTY) ? SVR4_O_NOCTTY : 0; 12743412Snewton return r; 12843412Snewton} 12943412Snewton 13043412Snewton 13143412Snewtonstatic void 13243412Snewtonbsd_to_svr4_flock(iflp, oflp) 13343412Snewton struct flock *iflp; 13443412Snewton struct svr4_flock *oflp; 13543412Snewton{ 13643412Snewton switch (iflp->l_type) { 13743412Snewton case F_RDLCK: 13843412Snewton oflp->l_type = SVR4_F_RDLCK; 13943412Snewton break; 14043412Snewton case F_WRLCK: 14143412Snewton oflp->l_type = SVR4_F_WRLCK; 14243412Snewton break; 14343412Snewton case F_UNLCK: 14443412Snewton oflp->l_type = SVR4_F_UNLCK; 14543412Snewton break; 14643412Snewton default: 14743412Snewton oflp->l_type = -1; 14843412Snewton break; 14943412Snewton } 15043412Snewton 15143412Snewton oflp->l_whence = (short) iflp->l_whence; 15243412Snewton oflp->l_start = (svr4_off_t) iflp->l_start; 15343412Snewton oflp->l_len = (svr4_off_t) iflp->l_len; 15443412Snewton oflp->l_sysid = 0; 15543412Snewton oflp->l_pid = (svr4_pid_t) iflp->l_pid; 15643412Snewton} 15743412Snewton 15843412Snewton 15943412Snewtonstatic void 16043412Snewtonsvr4_to_bsd_flock(iflp, oflp) 16143412Snewton struct svr4_flock *iflp; 16243412Snewton struct flock *oflp; 16343412Snewton{ 16443412Snewton switch (iflp->l_type) { 16543412Snewton case SVR4_F_RDLCK: 16643412Snewton oflp->l_type = F_RDLCK; 16743412Snewton break; 16843412Snewton case SVR4_F_WRLCK: 16943412Snewton oflp->l_type = F_WRLCK; 17043412Snewton break; 17143412Snewton case SVR4_F_UNLCK: 17243412Snewton oflp->l_type = F_UNLCK; 17343412Snewton break; 17443412Snewton default: 17543412Snewton oflp->l_type = -1; 17643412Snewton break; 17743412Snewton } 17843412Snewton 17943412Snewton oflp->l_whence = iflp->l_whence; 18043412Snewton oflp->l_start = (off_t) iflp->l_start; 18143412Snewton oflp->l_len = (off_t) iflp->l_len; 18243412Snewton oflp->l_pid = (pid_t) iflp->l_pid; 18343412Snewton 18443412Snewton} 18543412Snewton 18643412Snewtonstatic void 18743412Snewtonbsd_to_svr4_flock64(iflp, oflp) 18843412Snewton struct flock *iflp; 18943412Snewton struct svr4_flock64 *oflp; 19043412Snewton{ 19143412Snewton switch (iflp->l_type) { 19243412Snewton case F_RDLCK: 19343412Snewton oflp->l_type = SVR4_F_RDLCK; 19443412Snewton break; 19543412Snewton case F_WRLCK: 19643412Snewton oflp->l_type = SVR4_F_WRLCK; 19743412Snewton break; 19843412Snewton case F_UNLCK: 19943412Snewton oflp->l_type = SVR4_F_UNLCK; 20043412Snewton break; 20143412Snewton default: 20243412Snewton oflp->l_type = -1; 20343412Snewton break; 20443412Snewton } 20543412Snewton 20643412Snewton oflp->l_whence = (short) iflp->l_whence; 20743412Snewton oflp->l_start = (svr4_off64_t) iflp->l_start; 20843412Snewton oflp->l_len = (svr4_off64_t) iflp->l_len; 20943412Snewton oflp->l_sysid = 0; 21043412Snewton oflp->l_pid = (svr4_pid_t) iflp->l_pid; 21143412Snewton} 21243412Snewton 21343412Snewton 21443412Snewtonstatic void 21543412Snewtonsvr4_to_bsd_flock64(iflp, oflp) 21643412Snewton struct svr4_flock64 *iflp; 21743412Snewton struct flock *oflp; 21843412Snewton{ 21943412Snewton switch (iflp->l_type) { 22043412Snewton case SVR4_F_RDLCK: 22143412Snewton oflp->l_type = F_RDLCK; 22243412Snewton break; 22343412Snewton case SVR4_F_WRLCK: 22443412Snewton oflp->l_type = F_WRLCK; 22543412Snewton break; 22643412Snewton case SVR4_F_UNLCK: 22743412Snewton oflp->l_type = F_UNLCK; 22843412Snewton break; 22943412Snewton default: 23043412Snewton oflp->l_type = -1; 23143412Snewton break; 23243412Snewton } 23343412Snewton 23443412Snewton oflp->l_whence = iflp->l_whence; 23543412Snewton oflp->l_start = (off_t) iflp->l_start; 23643412Snewton oflp->l_len = (off_t) iflp->l_len; 23743412Snewton oflp->l_pid = (pid_t) iflp->l_pid; 23843412Snewton 23943412Snewton} 24043412Snewton 24143412Snewton 24243412Snewtonstatic int 24343412Snewtonfd_revoke(p, fd) 24443412Snewton struct proc *p; 24543412Snewton int fd; 24643412Snewton{ 24743412Snewton struct filedesc *fdp = p->p_fd; 24843412Snewton struct file *fp; 24943412Snewton struct vnode *vp; 25043412Snewton struct vattr vattr; 25143412Snewton int error, *retval; 25243412Snewton 25343412Snewton retval = p->p_retval; 25443412Snewton if ((u_int)fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL) 25543412Snewton return EBADF; 25643412Snewton 25743412Snewton switch (fp->f_type) { 25843412Snewton case DTYPE_VNODE: 25943412Snewton vp = (struct vnode *) fp->f_data; 26043412Snewton 26143412Snewton case DTYPE_SOCKET: 26243412Snewton return EINVAL; 26343412Snewton 26443412Snewton default: 26543412Snewton panic("svr4_fcntl(F_REVOKE)"); 26643412Snewton /*NOTREACHED*/ 26743412Snewton } 26843412Snewton 26943412Snewton if (vp->v_type != VCHR && vp->v_type != VBLK) { 27043412Snewton error = EINVAL; 27143412Snewton goto out; 27243412Snewton } 27343412Snewton 27443412Snewton if ((error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) != 0) 27543412Snewton goto out; 27643412Snewton 27743412Snewton if (p->p_ucred->cr_uid != vattr.va_uid && 27846112Sphk (error = suser(p)) != 0) 27943412Snewton goto out; 28043412Snewton 28143412Snewton if (vp->v_usecount > 1 || (vp->v_flag & VALIASED)) 28243412Snewton VOP_REVOKE(vp, REVOKEALL); 28343412Snewtonout: 28443412Snewton vrele(vp); 28543412Snewton return error; 28643412Snewton} 28743412Snewton 28843412Snewton 28943412Snewtonstatic int 29043412Snewtonfd_truncate(p, fd, flp) 29143412Snewton struct proc *p; 29243412Snewton int fd; 29343412Snewton struct flock *flp; 29443412Snewton{ 29543412Snewton struct filedesc *fdp = p->p_fd; 29643412Snewton struct file *fp; 29743412Snewton off_t start, length; 29843412Snewton struct vnode *vp; 29943412Snewton struct vattr vattr; 30043412Snewton int error, *retval; 30143412Snewton struct ftruncate_args ft; 30243412Snewton 30343412Snewton retval = p->p_retval; 30443412Snewton 30543412Snewton /* 30643412Snewton * We only support truncating the file. 30743412Snewton */ 30843412Snewton if ((u_int)fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL) 30943412Snewton return EBADF; 31043412Snewton 31143412Snewton vp = (struct vnode *)fp->f_data; 31243412Snewton if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) 31343412Snewton return ESPIPE; 31443412Snewton 31543412Snewton if ((error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) != 0) 31643412Snewton return error; 31743412Snewton 31843412Snewton length = vattr.va_size; 31943412Snewton 32043412Snewton switch (flp->l_whence) { 32143412Snewton case SEEK_CUR: 32243412Snewton start = fp->f_offset + flp->l_start; 32343412Snewton break; 32443412Snewton 32543412Snewton case SEEK_END: 32643412Snewton start = flp->l_start + length; 32743412Snewton break; 32843412Snewton 32943412Snewton case SEEK_SET: 33043412Snewton start = flp->l_start; 33143412Snewton break; 33243412Snewton 33343412Snewton default: 33443412Snewton return EINVAL; 33543412Snewton } 33643412Snewton 33743412Snewton if (start + flp->l_len < length) { 33843412Snewton /* We don't support free'ing in the middle of the file */ 33943412Snewton return EINVAL; 34043412Snewton } 34143412Snewton 34243412Snewton SCARG(&ft, fd) = fd; 34343412Snewton SCARG(&ft, length) = start; 34443412Snewton 34543412Snewton return ftruncate(p, &ft); 34643412Snewton} 34743412Snewton 34843412Snewtonint 34943412Snewtonsvr4_sys_open(p, uap) 35043412Snewton register struct proc *p; 35143412Snewton struct svr4_sys_open_args *uap; 35243412Snewton{ 35343412Snewton int error, retval; 35443412Snewton struct open_args cup; 35543412Snewton 35643412Snewton caddr_t sg = stackgap_init(); 35743412Snewton CHECKALTEXIST(p, &sg, SCARG(uap, path)); 35843412Snewton 35943412Snewton (&cup)->path = uap->path; 36043412Snewton (&cup)->flags = svr4_to_bsd_flags(uap->flags); 36143412Snewton (&cup)->mode = uap->mode; 36243412Snewton error = open(p, &cup); 36343412Snewton 36443412Snewton if (error) { 36543412Snewton /* uprintf("svr4_open(%s, 0x%0x, 0%o): %d\n", uap->path, 36643412Snewton uap->flags, uap->mode, error);*/ 36743412Snewton return error; 36843412Snewton } 36943412Snewton 37043412Snewton retval = p->p_retval[0]; 37143412Snewton 37243412Snewton if (!(SCARG(&cup, flags) & O_NOCTTY) && SESS_LEADER(p) && 37343412Snewton !(p->p_flag & P_CONTROLT)) { 37443412Snewton#if defined(NOTYET) 37543412Snewton struct filedesc *fdp = p->p_fd; 37643412Snewton struct file *fp = fdp->fd_ofiles[retval]; 37743412Snewton 37843412Snewton /* ignore any error, just give it a try */ 37943412Snewton if (fp->f_type == DTYPE_VNODE) 38043412Snewton (fp->f_ops->fo_ioctl) (fp, TIOCSCTTY, (caddr_t) 0, p); 38143412Snewton#endif 38243412Snewton } 38343412Snewton return error; 38443412Snewton} 38543412Snewton 38643412Snewtonint 38743412Snewtonsvr4_sys_open64(p, uap) 38843412Snewton register struct proc *p; 38943412Snewton struct svr4_sys_open64_args *uap; 39043412Snewton{ 39143412Snewton return svr4_sys_open(p, (struct svr4_sys_open_args *)uap); 39243412Snewton} 39343412Snewton 39443412Snewtonint 39543412Snewtonsvr4_sys_creat(p, uap) 39643412Snewton register struct proc *p; 39743412Snewton struct svr4_sys_creat_args *uap; 39843412Snewton{ 39943412Snewton struct open_args cup; 40043412Snewton 40143412Snewton caddr_t sg = stackgap_init(); 40243412Snewton CHECKALTEXIST(p, &sg, SCARG(uap, path)); 40343412Snewton 40443412Snewton SCARG(&cup, path) = SCARG(uap, path); 40543412Snewton SCARG(&cup, mode) = SCARG(uap, mode); 40643412Snewton SCARG(&cup, flags) = O_WRONLY | O_CREAT | O_TRUNC; 40743412Snewton 40843412Snewton return open(p, &cup); 40943412Snewton} 41043412Snewton 41143412Snewtonint 41243412Snewtonsvr4_sys_creat64(p, uap) 41343412Snewton register struct proc *p; 41443412Snewton struct svr4_sys_creat64_args *uap; 41543412Snewton{ 41643412Snewton return svr4_sys_creat(p, (struct svr4_sys_creat_args *)uap); 41743412Snewton} 41843412Snewton 41943412Snewtonint 42043412Snewtonsvr4_sys_llseek(p, v) 42143412Snewton register struct proc *p; 42243412Snewton struct svr4_sys_llseek_args *v; 42343412Snewton{ 42443412Snewton struct svr4_sys_llseek_args *uap = v; 42543412Snewton struct lseek_args ap; 42643412Snewton 42743412Snewton SCARG(&ap, fd) = SCARG(uap, fd); 42843412Snewton 42943412Snewton#if BYTE_ORDER == BIG_ENDIAN 43043412Snewton SCARG(&ap, offset) = (((long long) SCARG(uap, offset1)) << 32) | 43143412Snewton SCARG(uap, offset2); 43243412Snewton#else 43343412Snewton SCARG(&ap, offset) = (((long long) SCARG(uap, offset2)) << 32) | 43443412Snewton SCARG(uap, offset1); 43543412Snewton#endif 43643412Snewton SCARG(&ap, whence) = SCARG(uap, whence); 43743412Snewton 43843412Snewton return lseek(p, &ap); 43943412Snewton} 44043412Snewton 44143412Snewtonint 44243412Snewtonsvr4_sys_access(p, uap) 44343412Snewton register struct proc *p; 44443412Snewton struct svr4_sys_access_args *uap; 44543412Snewton{ 44643412Snewton struct access_args cup; 44743412Snewton int *retval; 44843412Snewton 44943412Snewton caddr_t sg = stackgap_init(); 45043412Snewton CHECKALTEXIST(p, &sg, SCARG(uap, path)); 45143412Snewton 45243412Snewton retval = p->p_retval; 45343412Snewton 45443412Snewton SCARG(&cup, path) = SCARG(uap, path); 45543412Snewton SCARG(&cup, flags) = SCARG(uap, flags); 45643412Snewton 45743412Snewton return access(p, &cup); 45843412Snewton} 45943412Snewton 46043412Snewton#if defined(NOTYET) 46143412Snewtonint 46243412Snewtonsvr4_sys_pread(p, uap) 46343412Snewton register struct proc *p; 46443412Snewton struct svr4_sys_pread_args *uap; 46543412Snewton{ 46643412Snewton struct pread_args pra; 46743412Snewton 46843412Snewton /* 46943412Snewton * Just translate the args structure and call the NetBSD 47043412Snewton * pread(2) system call (offset type is 64-bit in NetBSD). 47143412Snewton */ 47243412Snewton SCARG(&pra, fd) = SCARG(uap, fd); 47343412Snewton SCARG(&pra, buf) = SCARG(uap, buf); 47443412Snewton SCARG(&pra, nbyte) = SCARG(uap, nbyte); 47543412Snewton SCARG(&pra, offset) = SCARG(uap, off); 47643412Snewton 47743412Snewton return pread(p, &pra); 47843412Snewton} 47943412Snewton#endif 48043412Snewton 48143412Snewton#if defined(NOTYET) 48243412Snewtonint 48343412Snewtonsvr4_sys_pread64(p, v, retval) 48443412Snewton register struct proc *p; 48543412Snewton void *v; 48643412Snewton register_t *retval; 48743412Snewton{ 48843412Snewton 48943412Snewton struct svr4_sys_pread64_args *uap = v; 49043412Snewton struct sys_pread_args pra; 49143412Snewton 49243412Snewton /* 49343412Snewton * Just translate the args structure and call the NetBSD 49443412Snewton * pread(2) system call (offset type is 64-bit in NetBSD). 49543412Snewton */ 49643412Snewton SCARG(&pra, fd) = SCARG(uap, fd); 49743412Snewton SCARG(&pra, buf) = SCARG(uap, buf); 49843412Snewton SCARG(&pra, nbyte) = SCARG(uap, nbyte); 49943412Snewton SCARG(&pra, offset) = SCARG(uap, off); 50043412Snewton 50143412Snewton return (sys_pread(p, &pra, retval)); 50243412Snewton} 50343412Snewton#endif /* NOTYET */ 50443412Snewton 50543412Snewton#if defined(NOTYET) 50643412Snewtonint 50743412Snewtonsvr4_sys_pwrite(p, uap) 50843412Snewton register struct proc *p; 50943412Snewton struct svr4_sys_pwrite_args *uap; 51043412Snewton{ 51143412Snewton struct pwrite_args pwa; 51243412Snewton 51343412Snewton /* 51443412Snewton * Just translate the args structure and call the NetBSD 51543412Snewton * pwrite(2) system call (offset type is 64-bit in NetBSD). 51643412Snewton */ 51743412Snewton SCARG(&pwa, fd) = SCARG(uap, fd); 51843412Snewton SCARG(&pwa, buf) = SCARG(uap, buf); 51943412Snewton SCARG(&pwa, nbyte) = SCARG(uap, nbyte); 52043412Snewton SCARG(&pwa, offset) = SCARG(uap, off); 52143412Snewton 52243412Snewton return pwrite(p, &pwa); 52343412Snewton} 52443412Snewton#endif 52543412Snewton 52643412Snewton#if defined(NOTYET) 52743412Snewtonint 52843412Snewtonsvr4_sys_pwrite64(p, v, retval) 52943412Snewton register struct proc *p; 53043412Snewton void *v; 53143412Snewton register_t *retval; 53243412Snewton{ 53343412Snewton struct svr4_sys_pwrite64_args *uap = v; 53443412Snewton struct sys_pwrite_args pwa; 53543412Snewton 53643412Snewton /* 53743412Snewton * Just translate the args structure and call the NetBSD 53843412Snewton * pwrite(2) system call (offset type is 64-bit in NetBSD). 53943412Snewton */ 54043412Snewton SCARG(&pwa, fd) = SCARG(uap, fd); 54143412Snewton SCARG(&pwa, buf) = SCARG(uap, buf); 54243412Snewton SCARG(&pwa, nbyte) = SCARG(uap, nbyte); 54343412Snewton SCARG(&pwa, offset) = SCARG(uap, off); 54443412Snewton 54543412Snewton return (sys_pwrite(p, &pwa, retval)); 54643412Snewton} 54743412Snewton#endif /* NOTYET */ 54843412Snewton 54943412Snewtonint 55043412Snewtonsvr4_sys_fcntl(p, uap) 55143412Snewton register struct proc *p; 55243412Snewton struct svr4_sys_fcntl_args *uap; 55343412Snewton{ 55443412Snewton int error; 55543412Snewton struct fcntl_args fa; 55643412Snewton int *retval; 55743412Snewton 55843412Snewton retval = p->p_retval; 55943412Snewton 56043412Snewton SCARG(&fa, fd) = SCARG(uap, fd); 56143412Snewton SCARG(&fa, cmd) = svr4_to_bsd_cmd(SCARG(uap, cmd)); 56243412Snewton 56343412Snewton switch (SCARG(&fa, cmd)) { 56443412Snewton case F_DUPFD: 56543412Snewton case F_GETFD: 56643412Snewton case F_SETFD: 56743412Snewton SCARG(&fa, arg) = (long) SCARG(uap, arg); 56843412Snewton return fcntl(p, &fa); 56943412Snewton 57043412Snewton case F_GETFL: 57143412Snewton SCARG(&fa, arg) = (long) SCARG(uap, arg); 57243412Snewton error = fcntl(p, &fa); 57343412Snewton if (error) 57443412Snewton return error; 57543412Snewton *retval = bsd_to_svr4_flags(*retval); 57643412Snewton return error; 57743412Snewton 57843412Snewton case F_SETFL: 57943412Snewton { 58043412Snewton /* 58143412Snewton * we must save the O_ASYNC flag, as that is 58243412Snewton * handled by ioctl(_, I_SETSIG, _) emulation. 58343412Snewton */ 58443412Snewton long cmd; 58543412Snewton int flags; 58643412Snewton 58743412Snewton DPRINTF(("Setting flags 0x%x\n", SCARG(uap, arg))); 58843412Snewton cmd = SCARG(&fa, cmd); /* save it for a while */ 58943412Snewton 59043412Snewton SCARG(&fa, cmd) = F_GETFL; 59143412Snewton if ((error = fcntl(p, &fa)) != 0) 59243412Snewton return error; 59343412Snewton flags = *retval; 59443412Snewton flags &= O_ASYNC; 59543412Snewton flags |= svr4_to_bsd_flags((u_long) SCARG(uap, arg)); 59643412Snewton SCARG(&fa, cmd) = cmd; 59743412Snewton SCARG(&fa, arg) = (long) flags; 59843412Snewton return fcntl(p, &fa); 59943412Snewton } 60043412Snewton 60143412Snewton case F_GETLK: 60243412Snewton case F_SETLK: 60343412Snewton case F_SETLKW: 60443412Snewton { 60543412Snewton struct svr4_flock ifl; 60643412Snewton struct flock *flp, fl; 60743412Snewton caddr_t sg = stackgap_init(); 60843412Snewton 60943412Snewton flp = stackgap_alloc(&sg, sizeof(struct flock)); 61043412Snewton SCARG(&fa, arg) = (long) flp; 61143412Snewton 61243412Snewton error = copyin(SCARG(uap, arg), &ifl, sizeof ifl); 61343412Snewton if (error) 61443412Snewton return error; 61543412Snewton 61643412Snewton svr4_to_bsd_flock(&ifl, &fl); 61743412Snewton 61843412Snewton error = copyout(&fl, flp, sizeof fl); 61943412Snewton if (error) 62043412Snewton return error; 62143412Snewton 62243412Snewton error = fcntl(p, &fa); 62343412Snewton if (error || SCARG(&fa, cmd) != F_GETLK) 62443412Snewton return error; 62543412Snewton 62643412Snewton error = copyin(flp, &fl, sizeof fl); 62743412Snewton if (error) 62843412Snewton return error; 62943412Snewton 63043412Snewton bsd_to_svr4_flock(&fl, &ifl); 63143412Snewton 63243412Snewton return copyout(&ifl, SCARG(uap, arg), sizeof ifl); 63343412Snewton } 63443412Snewton case -1: 63543412Snewton switch (SCARG(uap, cmd)) { 63643412Snewton case SVR4_F_DUP2FD: 63743412Snewton { 63843412Snewton struct dup2_args du; 63943412Snewton 64043412Snewton SCARG(&du, from) = SCARG(uap, fd); 64143412Snewton SCARG(&du, to) = (int)SCARG(uap, arg); 64243412Snewton error = dup2(p, &du); 64343412Snewton if (error) 64443412Snewton return error; 64543412Snewton *retval = SCARG(&du, to); 64643412Snewton return 0; 64743412Snewton } 64843412Snewton 64943412Snewton case SVR4_F_FREESP: 65043412Snewton { 65143412Snewton struct svr4_flock ifl; 65243412Snewton struct flock fl; 65343412Snewton 65443412Snewton error = copyin(SCARG(uap, arg), &ifl, 65543412Snewton sizeof ifl); 65643412Snewton if (error) 65743412Snewton return error; 65843412Snewton svr4_to_bsd_flock(&ifl, &fl); 65943412Snewton return fd_truncate(p, SCARG(uap, fd), &fl); 66043412Snewton } 66143412Snewton 66243412Snewton case SVR4_F_GETLK64: 66343412Snewton case SVR4_F_SETLK64: 66443412Snewton case SVR4_F_SETLKW64: 66543412Snewton { 66643412Snewton struct svr4_flock64 ifl; 66743412Snewton struct flock *flp, fl; 66843412Snewton caddr_t sg = stackgap_init(); 66943412Snewton 67043412Snewton flp = stackgap_alloc(&sg, sizeof(struct flock)); 67143412Snewton SCARG(&fa, arg) = (long) flp; 67243412Snewton 67343412Snewton error = copyin(SCARG(uap, arg), &ifl, 67443412Snewton sizeof ifl); 67543412Snewton if (error) 67643412Snewton return error; 67743412Snewton 67843412Snewton svr4_to_bsd_flock64(&ifl, &fl); 67943412Snewton 68043412Snewton error = copyout(&fl, flp, sizeof fl); 68143412Snewton if (error) 68243412Snewton return error; 68343412Snewton 68443412Snewton error = fcntl(p, &fa); 68543412Snewton if (error || SCARG(&fa, cmd) != F_GETLK) 68643412Snewton return error; 68743412Snewton 68843412Snewton error = copyin(flp, &fl, sizeof fl); 68943412Snewton if (error) 69043412Snewton return error; 69143412Snewton 69243412Snewton bsd_to_svr4_flock64(&fl, &ifl); 69343412Snewton 69443412Snewton return copyout(&ifl, SCARG(uap, arg), 69543412Snewton sizeof ifl); 69643412Snewton } 69743412Snewton 69843412Snewton case SVR4_F_FREESP64: 69943412Snewton { 70043412Snewton struct svr4_flock64 ifl; 70143412Snewton struct flock fl; 70243412Snewton 70343412Snewton error = copyin(SCARG(uap, arg), &ifl, 70443412Snewton sizeof ifl); 70543412Snewton if (error) 70643412Snewton return error; 70743412Snewton svr4_to_bsd_flock64(&ifl, &fl); 70843412Snewton return fd_truncate(p, SCARG(uap, fd), &fl); 70943412Snewton } 71043412Snewton 71143412Snewton case SVR4_F_REVOKE: 71243412Snewton return fd_revoke(p, SCARG(uap, fd)); 71343412Snewton 71443412Snewton default: 71543412Snewton return ENOSYS; 71643412Snewton } 71743412Snewton 71843412Snewton default: 71943412Snewton return ENOSYS; 72043412Snewton } 72143412Snewton} 722