1139799Simp/*- 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. 2611394Sswallace */ 2711394Sswallace 28115684Sobrien#include <sys/cdefs.h> 29115684Sobrien__FBSDID("$FreeBSD$"); 30115684Sobrien 3133071Seivind#include "opt_spx_hack.h" 3233071Seivind 3311394Sswallace#include <sys/param.h> 3411394Sswallace#include <sys/systm.h> 35224778Srwatson#include <sys/capability.h> 3624131Sbde#include <sys/fcntl.h> 3711394Sswallace#include <sys/file.h> 3811394Sswallace#include <sys/filedesc.h> 3976166Smarkm#include <sys/lock.h> 40141488Sjhb#include <sys/malloc.h> 4176166Smarkm#include <sys/mutex.h> 42134266Sjhb#include <sys/syscallsubr.h> 4376166Smarkm#include <sys/sysproto.h> 4424206Sbde#include <sys/ttycom.h> 4511394Sswallace 4611397Sswallace#include <i386/ibcs2/ibcs2_fcntl.h> 4711397Sswallace#include <i386/ibcs2/ibcs2_signal.h> 4811397Sswallace#include <i386/ibcs2/ibcs2_proto.h> 4911397Sswallace#include <i386/ibcs2/ibcs2_util.h> 5011394Sswallace 5192761Salfredstatic void cvt_iflock2flock(struct ibcs2_flock *, struct flock *); 5292761Salfredstatic void cvt_flock2iflock(struct flock *, struct ibcs2_flock *); 5392761Salfredstatic int cvt_o_flags(int); 5492761Salfredstatic int oflags2ioflags(int); 5592761Salfredstatic int ioflags2oflags(int); 5611394Sswallace 5711394Sswallacestatic int 5811394Sswallacecvt_o_flags(flags) 5911394Sswallace int flags; 6011394Sswallace{ 6111394Sswallace int r = 0; 6211394Sswallace 6311394Sswallace /* convert mode into NetBSD mode */ 6411394Sswallace if (flags & IBCS2_O_WRONLY) r |= O_WRONLY; 6511397Sswallace if (flags & IBCS2_O_RDWR) r |= O_RDWR; 6611394Sswallace if (flags & (IBCS2_O_NDELAY | IBCS2_O_NONBLOCK)) r |= O_NONBLOCK; 6711394Sswallace if (flags & IBCS2_O_APPEND) r |= O_APPEND; 6811397Sswallace if (flags & IBCS2_O_SYNC) r |= O_FSYNC; 6911397Sswallace if (flags & IBCS2_O_CREAT) r |= O_CREAT; 7011397Sswallace if (flags & IBCS2_O_TRUNC) r |= O_TRUNC /* | O_CREAT ??? */; 7111397Sswallace if (flags & IBCS2_O_EXCL) r |= O_EXCL; 7211397Sswallace if (flags & IBCS2_O_RDONLY) r |= O_RDONLY; 7311397Sswallace if (flags & IBCS2_O_PRIV) r |= O_EXLOCK; 7411397Sswallace if (flags & IBCS2_O_NOCTTY) r |= O_NOCTTY; 7511394Sswallace return r; 7611394Sswallace} 7711394Sswallace 7811394Sswallacestatic void 7911394Sswallacecvt_flock2iflock(flp, iflp) 8011394Sswallace struct flock *flp; 8111394Sswallace struct ibcs2_flock *iflp; 8211394Sswallace{ 8311394Sswallace switch (flp->l_type) { 8411394Sswallace case F_RDLCK: 8511394Sswallace iflp->l_type = IBCS2_F_RDLCK; 8611394Sswallace break; 8711394Sswallace case F_WRLCK: 8811394Sswallace iflp->l_type = IBCS2_F_WRLCK; 8911394Sswallace break; 9011394Sswallace case F_UNLCK: 9111394Sswallace iflp->l_type = IBCS2_F_UNLCK; 9211394Sswallace break; 9311394Sswallace } 9411394Sswallace iflp->l_whence = (short)flp->l_whence; 9511394Sswallace iflp->l_start = (ibcs2_off_t)flp->l_start; 9611394Sswallace iflp->l_len = (ibcs2_off_t)flp->l_len; 97177633Sdfr iflp->l_sysid = flp->l_sysid; 9811394Sswallace iflp->l_pid = (ibcs2_pid_t)flp->l_pid; 9911394Sswallace} 10011394Sswallace 10111397Sswallace#ifdef DEBUG_IBCS2 10211394Sswallacestatic void 10311397Sswallaceprint_flock(struct flock *flp) 10411397Sswallace{ 10511397Sswallace printf("flock: start=%x len=%x pid=%d type=%d whence=%d\n", 10611397Sswallace (int)flp->l_start, (int)flp->l_len, (int)flp->l_pid, 10711397Sswallace flp->l_type, flp->l_whence); 10811397Sswallace} 10911397Sswallace#endif 11011397Sswallace 11111397Sswallacestatic void 11211394Sswallacecvt_iflock2flock(iflp, flp) 11311394Sswallace struct ibcs2_flock *iflp; 11411394Sswallace struct flock *flp; 11511394Sswallace{ 11611394Sswallace flp->l_start = (off_t)iflp->l_start; 11711394Sswallace flp->l_len = (off_t)iflp->l_len; 11811394Sswallace flp->l_pid = (pid_t)iflp->l_pid; 11911394Sswallace switch (iflp->l_type) { 12011394Sswallace case IBCS2_F_RDLCK: 12111394Sswallace flp->l_type = F_RDLCK; 12211394Sswallace break; 12311394Sswallace case IBCS2_F_WRLCK: 12411394Sswallace flp->l_type = F_WRLCK; 12511394Sswallace break; 12611394Sswallace case IBCS2_F_UNLCK: 12711394Sswallace flp->l_type = F_UNLCK; 12811394Sswallace break; 12911394Sswallace } 13011394Sswallace flp->l_whence = iflp->l_whence; 131177633Sdfr flp->l_sysid = iflp->l_sysid; 13211394Sswallace} 13311394Sswallace 13411394Sswallace/* convert iBCS2 mode into NetBSD mode */ 13511394Sswallacestatic int 13611394Sswallaceioflags2oflags(flags) 13711394Sswallace int flags; 13811394Sswallace{ 13911394Sswallace int r = 0; 14011394Sswallace 14111394Sswallace if (flags & IBCS2_O_RDONLY) r |= O_RDONLY; 14211394Sswallace if (flags & IBCS2_O_WRONLY) r |= O_WRONLY; 14311394Sswallace if (flags & IBCS2_O_RDWR) r |= O_RDWR; 14411394Sswallace if (flags & IBCS2_O_NDELAY) r |= O_NONBLOCK; 14511394Sswallace if (flags & IBCS2_O_APPEND) r |= O_APPEND; 14611394Sswallace if (flags & IBCS2_O_SYNC) r |= O_FSYNC; 14711394Sswallace if (flags & IBCS2_O_NONBLOCK) r |= O_NONBLOCK; 14811394Sswallace if (flags & IBCS2_O_CREAT) r |= O_CREAT; 14911394Sswallace if (flags & IBCS2_O_TRUNC) r |= O_TRUNC; 15011394Sswallace if (flags & IBCS2_O_EXCL) r |= O_EXCL; 15111394Sswallace if (flags & IBCS2_O_NOCTTY) r |= O_NOCTTY; 15211394Sswallace return r; 15311394Sswallace} 15411394Sswallace 15511394Sswallace/* convert NetBSD mode into iBCS2 mode */ 15611394Sswallacestatic int 15711394Sswallaceoflags2ioflags(flags) 15811394Sswallace int flags; 15911394Sswallace{ 16011394Sswallace int r = 0; 16111394Sswallace 16211394Sswallace if (flags & O_RDONLY) r |= IBCS2_O_RDONLY; 16311394Sswallace if (flags & O_WRONLY) r |= IBCS2_O_WRONLY; 16411394Sswallace if (flags & O_RDWR) r |= IBCS2_O_RDWR; 16511394Sswallace if (flags & O_NDELAY) r |= IBCS2_O_NONBLOCK; 16611394Sswallace if (flags & O_APPEND) r |= IBCS2_O_APPEND; 16711394Sswallace if (flags & O_FSYNC) r |= IBCS2_O_SYNC; 16811394Sswallace if (flags & O_NONBLOCK) r |= IBCS2_O_NONBLOCK; 16911394Sswallace if (flags & O_CREAT) r |= IBCS2_O_CREAT; 17011394Sswallace if (flags & O_TRUNC) r |= IBCS2_O_TRUNC; 17111394Sswallace if (flags & O_EXCL) r |= IBCS2_O_EXCL; 17211394Sswallace if (flags & O_NOCTTY) r |= IBCS2_O_NOCTTY; 17311394Sswallace return r; 17411394Sswallace} 17511394Sswallace 17611394Sswallaceint 17783366Sjulianibcs2_open(td, uap) 17883366Sjulian struct thread *td; 17911394Sswallace struct ibcs2_open_args *uap; 18011394Sswallace{ 181141488Sjhb struct proc *p; 182141488Sjhb char *path; 183141488Sjhb int flags, noctty, ret; 18411394Sswallace 185141488Sjhb p = td->td_proc; 186141488Sjhb noctty = uap->flags & IBCS2_O_NOCTTY; 187141488Sjhb flags = cvt_o_flags(uap->flags); 188107849Salfred if (uap->flags & O_CREAT) 189141488Sjhb CHECKALTCREAT(td, uap->path, &path); 19011394Sswallace else 191141488Sjhb CHECKALTEXIST(td, uap->path, &path); 192141488Sjhb ret = kern_open(td, path, UIO_SYSSPACE, flags, uap->mode); 19311394Sswallace 19411527Sswallace#ifdef SPX_HACK 19546568Speter if (ret == ENXIO) { 196141488Sjhb if (!strcmp(path, "/compat/ibcs2/dev/spx")) 197141488Sjhb ret = spx_open(td); 198141488Sjhb free(path, M_TEMP); 19946568Speter } else 20011527Sswallace#endif /* SPX_HACK */ 201141488Sjhb free(path, M_TEMP); 20271489Sjhb PROC_LOCK(p); 20311394Sswallace if (!ret && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { 20489306Salfred struct file *fp; 20589319Salfred int error; 20611394Sswallace 207224778Srwatson error = fget(td, td->td_retval[0], CAP_IOCTL, &fp); 20871489Sjhb PROC_UNLOCK(p); 20989319Salfred if (error) 21089306Salfred return (EBADF); 21189306Salfred 21211394Sswallace /* ignore any error, just give it a try */ 21311394Sswallace if (fp->f_type == DTYPE_VNODE) 214102003Srwatson fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td->td_ucred, 215102003Srwatson td); 21689306Salfred fdrop(fp, td); 21771489Sjhb } else 21871489Sjhb PROC_UNLOCK(p); 21911394Sswallace return ret; 22011394Sswallace} 22111394Sswallace 22211394Sswallaceint 22383366Sjulianibcs2_creat(td, uap) 22483366Sjulian struct thread *td; 22511394Sswallace struct ibcs2_creat_args *uap; 226141488Sjhb{ 227141488Sjhb char *path; 228141488Sjhb int error; 22911394Sswallace 230141488Sjhb CHECKALTCREAT(td, uap->path, &path); 231141488Sjhb error = kern_open(td, path, UIO_SYSSPACE, O_WRONLY | O_CREAT | O_TRUNC, 232141488Sjhb uap->mode); 233141488Sjhb free(path, M_TEMP); 234141488Sjhb return (error); 23511394Sswallace} 23611394Sswallace 23711394Sswallaceint 23883366Sjulianibcs2_access(td, uap) 23983366Sjulian struct thread *td; 24011394Sswallace struct ibcs2_access_args *uap; 24111394Sswallace{ 242141488Sjhb char *path; 243141488Sjhb int error; 24411394Sswallace 245141488Sjhb CHECKALTEXIST(td, uap->path, &path); 246141488Sjhb error = kern_access(td, path, UIO_SYSSPACE, uap->flags); 247141488Sjhb free(path, M_TEMP); 248141488Sjhb return (error); 24911394Sswallace} 25011394Sswallace 25111394Sswallaceint 25283366Sjulianibcs2_fcntl(td, uap) 25383366Sjulian struct thread *td; 25411394Sswallace struct ibcs2_fcntl_args *uap; 25511394Sswallace{ 256134266Sjhb intptr_t arg; 25711394Sswallace int error; 258134266Sjhb struct flock fl; 25911394Sswallace struct ibcs2_flock ifl; 260134266Sjhb 261134266Sjhb arg = (intptr_t)uap->arg; 262107849Salfred switch(uap->cmd) { 26311394Sswallace case IBCS2_F_DUPFD: 264134266Sjhb return (kern_fcntl(td, uap->fd, F_DUPFD, arg)); 26511394Sswallace case IBCS2_F_GETFD: 266134266Sjhb return (kern_fcntl(td, uap->fd, F_GETFD, arg)); 26711394Sswallace case IBCS2_F_SETFD: 268134266Sjhb return (kern_fcntl(td, uap->fd, F_SETFD, arg)); 26911394Sswallace case IBCS2_F_GETFL: 270134266Sjhb error = kern_fcntl(td, uap->fd, F_GETFL, arg); 27111394Sswallace if (error) 27211394Sswallace return error; 27383366Sjulian td->td_retval[0] = oflags2ioflags(td->td_retval[0]); 27411394Sswallace return error; 27511394Sswallace case IBCS2_F_SETFL: 276134266Sjhb return (kern_fcntl(td, uap->fd, F_SETFL, 277134266Sjhb ioflags2oflags(arg))); 27811394Sswallace 27911394Sswallace case IBCS2_F_GETLK: 28011394Sswallace { 281107849Salfred error = copyin((caddr_t)uap->arg, (caddr_t)&ifl, 28211394Sswallace ibcs2_flock_len); 28311394Sswallace if (error) 28411394Sswallace return error; 285134266Sjhb cvt_iflock2flock(&ifl, &fl); 286134266Sjhb error = kern_fcntl(td, uap->fd, F_GETLK, (intptr_t)&fl); 28711394Sswallace if (error) 28811394Sswallace return error; 289134266Sjhb cvt_flock2iflock(&fl, &ifl); 290107849Salfred return copyout((caddr_t)&ifl, (caddr_t)uap->arg, 29111394Sswallace ibcs2_flock_len); 29211394Sswallace } 29311394Sswallace 29411394Sswallace case IBCS2_F_SETLK: 29511394Sswallace { 296107849Salfred error = copyin((caddr_t)uap->arg, (caddr_t)&ifl, 29711394Sswallace ibcs2_flock_len); 29811394Sswallace if (error) 29911394Sswallace return error; 300134266Sjhb cvt_iflock2flock(&ifl, &fl); 301134266Sjhb return (kern_fcntl(td, uap->fd, F_SETLK, (intptr_t)&fl)); 30211394Sswallace } 30311394Sswallace 30411394Sswallace case IBCS2_F_SETLKW: 30511394Sswallace { 306107849Salfred error = copyin((caddr_t)uap->arg, (caddr_t)&ifl, 30711394Sswallace ibcs2_flock_len); 30811394Sswallace if (error) 30911394Sswallace return error; 310134266Sjhb cvt_iflock2flock(&ifl, &fl); 311134266Sjhb return (kern_fcntl(td, uap->fd, F_SETLKW, (intptr_t)&fl)); 31211394Sswallace } 31311394Sswallace } 31411394Sswallace return ENOSYS; 31511394Sswallace} 316