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