ibcs2_fcntl.c revision 92761
111394Sswallace/* 211394Sswallace * Copyright (c) 1995 Scott Bartram 311394Sswallace * All rights reserved. 411394Sswallace * 511394Sswallace * Redistribution and use in source and binary forms, with or without 611394Sswallace * modification, are permitted provided that the following conditions 711394Sswallace * are met: 811394Sswallace * 1. Redistributions of source code must retain the above copyright 911394Sswallace * notice, this list of conditions and the following disclaimer. 1011394Sswallace * 2. Redistributions in binary form must reproduce the above copyright 1111394Sswallace * notice, this list of conditions and the following disclaimer in the 1211394Sswallace * documentation and/or other materials provided with the distribution. 1311394Sswallace * 3. The name of the author may not be used to endorse or promote products 1411394Sswallace * derived from this software without specific prior written permission 1511394Sswallace * 1611394Sswallace * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1711394Sswallace * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1811394Sswallace * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1911394Sswallace * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2011394Sswallace * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2111394Sswallace * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2211394Sswallace * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2311394Sswallace * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2411394Sswallace * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2511394Sswallace * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2611527Sswallace * 2750477Speter * $FreeBSD: head/sys/i386/ibcs2/ibcs2_fcntl.c 92761 2002-03-20 05:48:58Z alfred $ 2811394Sswallace */ 2911394Sswallace 3033071Seivind#include "opt_spx_hack.h" 3133071Seivind 3211394Sswallace#include <sys/param.h> 3311394Sswallace#include <sys/systm.h> 3424131Sbde#include <sys/fcntl.h> 3511394Sswallace#include <sys/file.h> 3611394Sswallace#include <sys/filedesc.h> 3776166Smarkm#include <sys/lock.h> 3876166Smarkm#include <sys/mutex.h> 3976166Smarkm#include <sys/sysproto.h> 4024206Sbde#include <sys/ttycom.h> 4111394Sswallace 4211397Sswallace#include <i386/ibcs2/ibcs2_fcntl.h> 4311397Sswallace#include <i386/ibcs2/ibcs2_signal.h> 4411397Sswallace#include <i386/ibcs2/ibcs2_proto.h> 4511397Sswallace#include <i386/ibcs2/ibcs2_util.h> 4611394Sswallace 4792761Salfredstatic void cvt_iflock2flock(struct ibcs2_flock *, struct flock *); 4892761Salfredstatic void cvt_flock2iflock(struct flock *, struct ibcs2_flock *); 4992761Salfredstatic int cvt_o_flags(int); 5092761Salfredstatic int oflags2ioflags(int); 5192761Salfredstatic int ioflags2oflags(int); 5211394Sswallace 5311394Sswallacestatic int 5411394Sswallacecvt_o_flags(flags) 5511394Sswallace int flags; 5611394Sswallace{ 5711394Sswallace int r = 0; 5811394Sswallace 5911394Sswallace /* convert mode into NetBSD mode */ 6011394Sswallace if (flags & IBCS2_O_WRONLY) r |= O_WRONLY; 6111397Sswallace if (flags & IBCS2_O_RDWR) r |= O_RDWR; 6211394Sswallace if (flags & (IBCS2_O_NDELAY | IBCS2_O_NONBLOCK)) r |= O_NONBLOCK; 6311394Sswallace if (flags & IBCS2_O_APPEND) r |= O_APPEND; 6411397Sswallace if (flags & IBCS2_O_SYNC) r |= O_FSYNC; 6511397Sswallace if (flags & IBCS2_O_CREAT) r |= O_CREAT; 6611397Sswallace if (flags & IBCS2_O_TRUNC) r |= O_TRUNC /* | O_CREAT ??? */; 6711397Sswallace if (flags & IBCS2_O_EXCL) r |= O_EXCL; 6811397Sswallace if (flags & IBCS2_O_RDONLY) r |= O_RDONLY; 6911397Sswallace if (flags & IBCS2_O_PRIV) r |= O_EXLOCK; 7011397Sswallace if (flags & IBCS2_O_NOCTTY) r |= O_NOCTTY; 7111394Sswallace return r; 7211394Sswallace} 7311394Sswallace 7411394Sswallacestatic void 7511394Sswallacecvt_flock2iflock(flp, iflp) 7611394Sswallace struct flock *flp; 7711394Sswallace struct ibcs2_flock *iflp; 7811394Sswallace{ 7911394Sswallace switch (flp->l_type) { 8011394Sswallace case F_RDLCK: 8111394Sswallace iflp->l_type = IBCS2_F_RDLCK; 8211394Sswallace break; 8311394Sswallace case F_WRLCK: 8411394Sswallace iflp->l_type = IBCS2_F_WRLCK; 8511394Sswallace break; 8611394Sswallace case F_UNLCK: 8711394Sswallace iflp->l_type = IBCS2_F_UNLCK; 8811394Sswallace break; 8911394Sswallace } 9011394Sswallace iflp->l_whence = (short)flp->l_whence; 9111394Sswallace iflp->l_start = (ibcs2_off_t)flp->l_start; 9211394Sswallace iflp->l_len = (ibcs2_off_t)flp->l_len; 9311394Sswallace iflp->l_sysid = 0; 9411394Sswallace iflp->l_pid = (ibcs2_pid_t)flp->l_pid; 9511394Sswallace} 9611394Sswallace 9711397Sswallace#ifdef DEBUG_IBCS2 9811394Sswallacestatic void 9911397Sswallaceprint_flock(struct flock *flp) 10011397Sswallace{ 10111397Sswallace printf("flock: start=%x len=%x pid=%d type=%d whence=%d\n", 10211397Sswallace (int)flp->l_start, (int)flp->l_len, (int)flp->l_pid, 10311397Sswallace flp->l_type, flp->l_whence); 10411397Sswallace} 10511397Sswallace#endif 10611397Sswallace 10711397Sswallacestatic void 10811394Sswallacecvt_iflock2flock(iflp, flp) 10911394Sswallace struct ibcs2_flock *iflp; 11011394Sswallace struct flock *flp; 11111394Sswallace{ 11211394Sswallace flp->l_start = (off_t)iflp->l_start; 11311394Sswallace flp->l_len = (off_t)iflp->l_len; 11411394Sswallace flp->l_pid = (pid_t)iflp->l_pid; 11511394Sswallace switch (iflp->l_type) { 11611394Sswallace case IBCS2_F_RDLCK: 11711394Sswallace flp->l_type = F_RDLCK; 11811394Sswallace break; 11911394Sswallace case IBCS2_F_WRLCK: 12011394Sswallace flp->l_type = F_WRLCK; 12111394Sswallace break; 12211394Sswallace case IBCS2_F_UNLCK: 12311394Sswallace flp->l_type = F_UNLCK; 12411394Sswallace break; 12511394Sswallace } 12611394Sswallace flp->l_whence = iflp->l_whence; 12711394Sswallace} 12811394Sswallace 12911394Sswallace/* convert iBCS2 mode into NetBSD mode */ 13011394Sswallacestatic int 13111394Sswallaceioflags2oflags(flags) 13211394Sswallace int flags; 13311394Sswallace{ 13411394Sswallace int r = 0; 13511394Sswallace 13611394Sswallace if (flags & IBCS2_O_RDONLY) r |= O_RDONLY; 13711394Sswallace if (flags & IBCS2_O_WRONLY) r |= O_WRONLY; 13811394Sswallace if (flags & IBCS2_O_RDWR) r |= O_RDWR; 13911394Sswallace if (flags & IBCS2_O_NDELAY) r |= O_NONBLOCK; 14011394Sswallace if (flags & IBCS2_O_APPEND) r |= O_APPEND; 14111394Sswallace if (flags & IBCS2_O_SYNC) r |= O_FSYNC; 14211394Sswallace if (flags & IBCS2_O_NONBLOCK) r |= O_NONBLOCK; 14311394Sswallace if (flags & IBCS2_O_CREAT) r |= O_CREAT; 14411394Sswallace if (flags & IBCS2_O_TRUNC) r |= O_TRUNC; 14511394Sswallace if (flags & IBCS2_O_EXCL) r |= O_EXCL; 14611394Sswallace if (flags & IBCS2_O_NOCTTY) r |= O_NOCTTY; 14711394Sswallace return r; 14811394Sswallace} 14911394Sswallace 15011394Sswallace/* convert NetBSD mode into iBCS2 mode */ 15111394Sswallacestatic int 15211394Sswallaceoflags2ioflags(flags) 15311394Sswallace int flags; 15411394Sswallace{ 15511394Sswallace int r = 0; 15611394Sswallace 15711394Sswallace if (flags & O_RDONLY) r |= IBCS2_O_RDONLY; 15811394Sswallace if (flags & O_WRONLY) r |= IBCS2_O_WRONLY; 15911394Sswallace if (flags & O_RDWR) r |= IBCS2_O_RDWR; 16011394Sswallace if (flags & O_NDELAY) r |= IBCS2_O_NONBLOCK; 16111394Sswallace if (flags & O_APPEND) r |= IBCS2_O_APPEND; 16211394Sswallace if (flags & O_FSYNC) r |= IBCS2_O_SYNC; 16311394Sswallace if (flags & O_NONBLOCK) r |= IBCS2_O_NONBLOCK; 16411394Sswallace if (flags & O_CREAT) r |= IBCS2_O_CREAT; 16511394Sswallace if (flags & O_TRUNC) r |= IBCS2_O_TRUNC; 16611394Sswallace if (flags & O_EXCL) r |= IBCS2_O_EXCL; 16711394Sswallace if (flags & O_NOCTTY) r |= IBCS2_O_NOCTTY; 16811394Sswallace return r; 16911394Sswallace} 17011394Sswallace 17111394Sswallaceint 17283366Sjulianibcs2_open(td, uap) 17383366Sjulian struct thread *td; 17411394Sswallace struct ibcs2_open_args *uap; 17511394Sswallace{ 17683366Sjulian struct proc *p = td->td_proc; 17711394Sswallace int noctty = SCARG(uap, flags) & IBCS2_O_NOCTTY; 17811394Sswallace int ret; 17911394Sswallace caddr_t sg = stackgap_init(); 18011394Sswallace 18111394Sswallace SCARG(uap, flags) = cvt_o_flags(SCARG(uap, flags)); 18211394Sswallace if (SCARG(uap, flags) & O_CREAT) 18383366Sjulian CHECKALTCREAT(td, &sg, SCARG(uap, path)); 18411394Sswallace else 18583366Sjulian CHECKALTEXIST(td, &sg, SCARG(uap, path)); 18683366Sjulian ret = open(td, (struct open_args *)uap); 18711394Sswallace 18811527Sswallace#ifdef SPX_HACK 18946568Speter if (ret == ENXIO) { 19046568Speter if (!strcmp(SCARG(uap, path), "/compat/ibcs2/dev/spx")) 19183366Sjulian ret = spx_open(td, uap); 19246568Speter } else 19311527Sswallace#endif /* SPX_HACK */ 19471489Sjhb PROC_LOCK(p); 19511394Sswallace if (!ret && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { 19689306Salfred struct file *fp; 19789319Salfred int error; 19811394Sswallace 19989319Salfred error = fget(td, td->td_retval[0], &fp); 20071489Sjhb PROC_UNLOCK(p); 20189319Salfred if (error) 20289306Salfred return (EBADF); 20389306Salfred 20411394Sswallace /* ignore any error, just give it a try */ 20511394Sswallace if (fp->f_type == DTYPE_VNODE) 20683366Sjulian fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td); 20789306Salfred fdrop(fp, td); 20871489Sjhb } else 20971489Sjhb PROC_UNLOCK(p); 21011394Sswallace return ret; 21111394Sswallace} 21211394Sswallace 21311394Sswallaceint 21483366Sjulianibcs2_creat(td, uap) 21583366Sjulian struct thread *td; 21611394Sswallace struct ibcs2_creat_args *uap; 21711394Sswallace{ 21811394Sswallace struct open_args cup; 21911394Sswallace caddr_t sg = stackgap_init(); 22011394Sswallace 22183366Sjulian CHECKALTCREAT(td, &sg, SCARG(uap, path)); 22211394Sswallace SCARG(&cup, path) = SCARG(uap, path); 22311394Sswallace SCARG(&cup, mode) = SCARG(uap, mode); 22411394Sswallace SCARG(&cup, flags) = O_WRONLY | O_CREAT | O_TRUNC; 22583366Sjulian return open(td, &cup); 22611394Sswallace} 22711394Sswallace 22811394Sswallaceint 22983366Sjulianibcs2_access(td, uap) 23083366Sjulian struct thread *td; 23111394Sswallace struct ibcs2_access_args *uap; 23211394Sswallace{ 23311394Sswallace struct access_args cup; 23411394Sswallace caddr_t sg = stackgap_init(); 23511394Sswallace 23683366Sjulian CHECKALTEXIST(td, &sg, SCARG(uap, path)); 23711394Sswallace SCARG(&cup, path) = SCARG(uap, path); 23811394Sswallace SCARG(&cup, flags) = SCARG(uap, flags); 23983366Sjulian return access(td, &cup); 24011394Sswallace} 24111394Sswallace 24211394Sswallaceint 24383366Sjulianibcs2_fcntl(td, uap) 24483366Sjulian struct thread *td; 24511394Sswallace struct ibcs2_fcntl_args *uap; 24611394Sswallace{ 24711394Sswallace int error; 24811394Sswallace struct fcntl_args fa; 24911394Sswallace struct flock *flp; 25011394Sswallace struct ibcs2_flock ifl; 25111394Sswallace 25211394Sswallace switch(SCARG(uap, cmd)) { 25311394Sswallace case IBCS2_F_DUPFD: 25411394Sswallace SCARG(&fa, fd) = SCARG(uap, fd); 25511394Sswallace SCARG(&fa, cmd) = F_DUPFD; 25612218Sbde SCARG(&fa, arg) = (/* XXX */ int)SCARG(uap, arg); 25783366Sjulian return fcntl(td, &fa); 25811394Sswallace case IBCS2_F_GETFD: 25911394Sswallace SCARG(&fa, fd) = SCARG(uap, fd); 26011394Sswallace SCARG(&fa, cmd) = F_GETFD; 26112218Sbde SCARG(&fa, arg) = (/* XXX */ int)SCARG(uap, arg); 26283366Sjulian return fcntl(td, &fa); 26311394Sswallace case IBCS2_F_SETFD: 26411394Sswallace SCARG(&fa, fd) = SCARG(uap, fd); 26511394Sswallace SCARG(&fa, cmd) = F_SETFD; 26612218Sbde SCARG(&fa, arg) = (/* XXX */ int)SCARG(uap, arg); 26783366Sjulian return fcntl(td, &fa); 26811394Sswallace case IBCS2_F_GETFL: 26911394Sswallace SCARG(&fa, fd) = SCARG(uap, fd); 27011394Sswallace SCARG(&fa, cmd) = F_GETFL; 27112218Sbde SCARG(&fa, arg) = (/* XXX */ int)SCARG(uap, arg); 27283366Sjulian error = fcntl(td, &fa); 27311394Sswallace if (error) 27411394Sswallace return error; 27583366Sjulian td->td_retval[0] = oflags2ioflags(td->td_retval[0]); 27611394Sswallace return error; 27711394Sswallace case IBCS2_F_SETFL: 27811394Sswallace SCARG(&fa, fd) = SCARG(uap, fd); 27911394Sswallace SCARG(&fa, cmd) = F_SETFL; 28012218Sbde SCARG(&fa, arg) = (/* XXX */ int) 28112218Sbde ioflags2oflags((int)SCARG(uap, arg)); 28283366Sjulian return fcntl(td, &fa); 28311394Sswallace 28411394Sswallace case IBCS2_F_GETLK: 28511394Sswallace { 28611394Sswallace caddr_t sg = stackgap_init(); 28711394Sswallace flp = stackgap_alloc(&sg, sizeof(*flp)); 28811394Sswallace error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&ifl, 28911394Sswallace ibcs2_flock_len); 29011394Sswallace if (error) 29111394Sswallace return error; 29211394Sswallace cvt_iflock2flock(&ifl, flp); 29311394Sswallace SCARG(&fa, fd) = SCARG(uap, fd); 29411394Sswallace SCARG(&fa, cmd) = F_GETLK; 29512218Sbde SCARG(&fa, arg) = (/* XXX */ int)flp; 29683366Sjulian error = fcntl(td, &fa); 29711394Sswallace if (error) 29811394Sswallace return error; 29911394Sswallace cvt_flock2iflock(flp, &ifl); 30011394Sswallace return copyout((caddr_t)&ifl, (caddr_t)SCARG(uap, arg), 30111394Sswallace ibcs2_flock_len); 30211394Sswallace } 30311394Sswallace 30411394Sswallace case IBCS2_F_SETLK: 30511394Sswallace { 30611394Sswallace caddr_t sg = stackgap_init(); 30711394Sswallace flp = stackgap_alloc(&sg, sizeof(*flp)); 30811394Sswallace error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&ifl, 30911394Sswallace ibcs2_flock_len); 31011394Sswallace if (error) 31111394Sswallace return error; 31211394Sswallace cvt_iflock2flock(&ifl, flp); 31311394Sswallace SCARG(&fa, fd) = SCARG(uap, fd); 31411394Sswallace SCARG(&fa, cmd) = F_SETLK; 31512218Sbde SCARG(&fa, arg) = (/* XXX */ int)flp; 31611397Sswallace 31783366Sjulian return fcntl(td, &fa); 31811394Sswallace } 31911394Sswallace 32011394Sswallace case IBCS2_F_SETLKW: 32111394Sswallace { 32211394Sswallace caddr_t sg = stackgap_init(); 32311394Sswallace flp = stackgap_alloc(&sg, sizeof(*flp)); 32411394Sswallace error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&ifl, 32511394Sswallace ibcs2_flock_len); 32611394Sswallace if (error) 32711394Sswallace return error; 32811394Sswallace cvt_iflock2flock(&ifl, flp); 32911394Sswallace SCARG(&fa, fd) = SCARG(uap, fd); 33011394Sswallace SCARG(&fa, cmd) = F_SETLKW; 33112218Sbde SCARG(&fa, arg) = (/* XXX */ int)flp; 33283366Sjulian return fcntl(td, &fa); 33311394Sswallace } 33411394Sswallace } 33511394Sswallace return ENOSYS; 33611394Sswallace} 337