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