ibcs2_fcntl.c revision 24131
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 *
2724131Sbde * $Id: ibcs2_fcntl.c,v 1.6 1997/02/22 09:33:18 peter Exp $
2811394Sswallace */
2911394Sswallace
3011394Sswallace#include <sys/param.h>
3111394Sswallace#include <sys/systm.h>
3211394Sswallace#include <sys/namei.h>
3311394Sswallace#include <sys/proc.h>
3424131Sbde#include <sys/fcntl.h>
3511394Sswallace#include <sys/file.h>
3611394Sswallace#include <sys/stat.h>
3711394Sswallace#include <sys/filedesc.h>
3811394Sswallace#include <sys/ioctl.h>
3911394Sswallace#include <sys/kernel.h>
4011394Sswallace#include <sys/mount.h>
4111394Sswallace#include <sys/malloc.h>
4211397Sswallace#include <sys/sysproto.h>
4311394Sswallace
4411397Sswallace#include <i386/ibcs2/ibcs2_types.h>
4511397Sswallace#include <i386/ibcs2/ibcs2_fcntl.h>
4611397Sswallace#include <i386/ibcs2/ibcs2_signal.h>
4711397Sswallace#include <i386/ibcs2/ibcs2_proto.h>
4811397Sswallace#include <i386/ibcs2/ibcs2_util.h>
4911394Sswallace
5011397Sswallacestatic void cvt_iflock2flock __P((struct ibcs2_flock *, struct flock *));
5111397Sswallacestatic void cvt_flock2iflock __P((struct flock *, struct ibcs2_flock *));
5211397Sswallacestatic int  cvt_o_flags      __P((int));
5311397Sswallacestatic int  oflags2ioflags   __P((int));
5411397Sswallacestatic int  ioflags2oflags   __P((int));
5511394Sswallace
5611394Sswallacestatic int
5711394Sswallacecvt_o_flags(flags)
5811394Sswallace	int flags;
5911394Sswallace{
6011394Sswallace	int r = 0;
6111394Sswallace
6211394Sswallace        /* convert mode into NetBSD mode */
6311394Sswallace	if (flags & IBCS2_O_WRONLY) r |= O_WRONLY;
6411397Sswallace	if (flags & IBCS2_O_RDWR)   r |= O_RDWR;
6511394Sswallace	if (flags & (IBCS2_O_NDELAY | IBCS2_O_NONBLOCK)) r |= O_NONBLOCK;
6611394Sswallace	if (flags & IBCS2_O_APPEND) r |= O_APPEND;
6711397Sswallace	if (flags & IBCS2_O_SYNC)   r |= O_FSYNC;
6811397Sswallace	if (flags & IBCS2_O_CREAT)  r |= O_CREAT;
6911397Sswallace	if (flags & IBCS2_O_TRUNC)  r |= O_TRUNC /* | O_CREAT ??? */;
7011397Sswallace	if (flags & IBCS2_O_EXCL)   r |= O_EXCL;
7111397Sswallace	if (flags & IBCS2_O_RDONLY) r |= O_RDONLY;
7211397Sswallace	if (flags & IBCS2_O_PRIV)   r |= O_EXLOCK;
7311397Sswallace	if (flags & IBCS2_O_NOCTTY) r |= O_NOCTTY;
7411394Sswallace	return r;
7511394Sswallace}
7611394Sswallace
7711394Sswallacestatic void
7811394Sswallacecvt_flock2iflock(flp, iflp)
7911394Sswallace	struct flock *flp;
8011394Sswallace	struct ibcs2_flock *iflp;
8111394Sswallace{
8211394Sswallace	switch (flp->l_type) {
8311394Sswallace	case F_RDLCK:
8411394Sswallace		iflp->l_type = IBCS2_F_RDLCK;
8511394Sswallace		break;
8611394Sswallace	case F_WRLCK:
8711394Sswallace		iflp->l_type = IBCS2_F_WRLCK;
8811394Sswallace		break;
8911394Sswallace	case F_UNLCK:
9011394Sswallace		iflp->l_type = IBCS2_F_UNLCK;
9111394Sswallace		break;
9211394Sswallace	}
9311394Sswallace	iflp->l_whence = (short)flp->l_whence;
9411394Sswallace	iflp->l_start = (ibcs2_off_t)flp->l_start;
9511394Sswallace	iflp->l_len = (ibcs2_off_t)flp->l_len;
9611394Sswallace	iflp->l_sysid = 0;
9711394Sswallace	iflp->l_pid = (ibcs2_pid_t)flp->l_pid;
9811394Sswallace}
9911394Sswallace
10011397Sswallace#ifdef DEBUG_IBCS2
10111394Sswallacestatic void
10211397Sswallaceprint_flock(struct flock *flp)
10311397Sswallace{
10411397Sswallace  printf("flock: start=%x len=%x pid=%d type=%d whence=%d\n",
10511397Sswallace	 (int)flp->l_start, (int)flp->l_len, (int)flp->l_pid,
10611397Sswallace	 flp->l_type, flp->l_whence);
10711397Sswallace}
10811397Sswallace#endif
10911397Sswallace
11011397Sswallacestatic void
11111394Sswallacecvt_iflock2flock(iflp, flp)
11211394Sswallace	struct ibcs2_flock *iflp;
11311394Sswallace	struct flock *flp;
11411394Sswallace{
11511394Sswallace	flp->l_start = (off_t)iflp->l_start;
11611394Sswallace	flp->l_len = (off_t)iflp->l_len;
11711394Sswallace	flp->l_pid = (pid_t)iflp->l_pid;
11811394Sswallace	switch (iflp->l_type) {
11911394Sswallace	case IBCS2_F_RDLCK:
12011394Sswallace		flp->l_type = F_RDLCK;
12111394Sswallace		break;
12211394Sswallace	case IBCS2_F_WRLCK:
12311394Sswallace		flp->l_type = F_WRLCK;
12411394Sswallace		break;
12511394Sswallace	case IBCS2_F_UNLCK:
12611394Sswallace		flp->l_type = F_UNLCK;
12711394Sswallace		break;
12811394Sswallace	}
12911394Sswallace	flp->l_whence = iflp->l_whence;
13011394Sswallace}
13111394Sswallace
13211394Sswallace/* convert iBCS2 mode into NetBSD mode */
13311394Sswallacestatic int
13411394Sswallaceioflags2oflags(flags)
13511394Sswallace	int flags;
13611394Sswallace{
13711394Sswallace	int r = 0;
13811394Sswallace
13911394Sswallace	if (flags & IBCS2_O_RDONLY) r |= O_RDONLY;
14011394Sswallace	if (flags & IBCS2_O_WRONLY) r |= O_WRONLY;
14111394Sswallace	if (flags & IBCS2_O_RDWR) r |= O_RDWR;
14211394Sswallace	if (flags & IBCS2_O_NDELAY) r |= O_NONBLOCK;
14311394Sswallace	if (flags & IBCS2_O_APPEND) r |= O_APPEND;
14411394Sswallace	if (flags & IBCS2_O_SYNC) r |= O_FSYNC;
14511394Sswallace	if (flags & IBCS2_O_NONBLOCK) r |= O_NONBLOCK;
14611394Sswallace	if (flags & IBCS2_O_CREAT) r |= O_CREAT;
14711394Sswallace	if (flags & IBCS2_O_TRUNC) r |= O_TRUNC;
14811394Sswallace	if (flags & IBCS2_O_EXCL) r |= O_EXCL;
14911394Sswallace	if (flags & IBCS2_O_NOCTTY) r |= O_NOCTTY;
15011394Sswallace	return r;
15111394Sswallace}
15211394Sswallace
15311394Sswallace/* convert NetBSD mode into iBCS2 mode */
15411394Sswallacestatic int
15511394Sswallaceoflags2ioflags(flags)
15611394Sswallace	int flags;
15711394Sswallace{
15811394Sswallace	int r = 0;
15911394Sswallace
16011394Sswallace	if (flags & O_RDONLY) r |= IBCS2_O_RDONLY;
16111394Sswallace	if (flags & O_WRONLY) r |= IBCS2_O_WRONLY;
16211394Sswallace	if (flags & O_RDWR) r |= IBCS2_O_RDWR;
16311394Sswallace	if (flags & O_NDELAY) r |= IBCS2_O_NONBLOCK;
16411394Sswallace	if (flags & O_APPEND) r |= IBCS2_O_APPEND;
16511394Sswallace	if (flags & O_FSYNC) r |= IBCS2_O_SYNC;
16611394Sswallace	if (flags & O_NONBLOCK) r |= IBCS2_O_NONBLOCK;
16711394Sswallace	if (flags & O_CREAT) r |= IBCS2_O_CREAT;
16811394Sswallace	if (flags & O_TRUNC) r |= IBCS2_O_TRUNC;
16911394Sswallace	if (flags & O_EXCL) r |= IBCS2_O_EXCL;
17011394Sswallace	if (flags & O_NOCTTY) r |= IBCS2_O_NOCTTY;
17111394Sswallace	return r;
17211394Sswallace}
17311394Sswallace
17411394Sswallaceint
17511394Sswallaceibcs2_open(p, uap, retval)
17611394Sswallace	struct proc *p;
17711394Sswallace	struct ibcs2_open_args *uap;
17811394Sswallace	int *retval;
17911394Sswallace{
18011394Sswallace	int noctty = SCARG(uap, flags) & IBCS2_O_NOCTTY;
18111394Sswallace	int ret;
18211394Sswallace	caddr_t sg = stackgap_init();
18311394Sswallace
18411394Sswallace	SCARG(uap, flags) = cvt_o_flags(SCARG(uap, flags));
18511394Sswallace	if (SCARG(uap, flags) & O_CREAT)
18611394Sswallace		CHECKALTCREAT(p, &sg, SCARG(uap, path));
18711394Sswallace	else
18811394Sswallace		CHECKALTEXIST(p, &sg, SCARG(uap, path));
18911397Sswallace	ret = open(p, (struct open_args *)uap, retval);
19011394Sswallace
19111527Sswallace#ifdef SPX_HACK
19211527Sswallace	if(ret == ENXIO)
19311527Sswallace		if(!strcmp(SCARG(uap, path), "/compat/ibcs2/dev/spx"))
19411527Sswallace			ret = spx_open(p, uap, retval);
19511527Sswallace	else
19611527Sswallace#endif /* SPX_HACK */
19711394Sswallace	if (!ret && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
19811394Sswallace		struct filedesc *fdp = p->p_fd;
19911394Sswallace		struct file *fp = fdp->fd_ofiles[*retval];
20011394Sswallace
20111394Sswallace		/* ignore any error, just give it a try */
20211394Sswallace		if (fp->f_type == DTYPE_VNODE)
20311394Sswallace			(fp->f_ops->fo_ioctl)(fp, TIOCSCTTY, (caddr_t) 0, p);
20411394Sswallace	}
20511394Sswallace	return ret;
20611394Sswallace}
20711394Sswallace
20811394Sswallaceint
20911394Sswallaceibcs2_creat(p, uap, retval)
21011394Sswallace        struct proc *p;
21111394Sswallace	struct ibcs2_creat_args *uap;
21211394Sswallace	int *retval;
21311394Sswallace{
21411394Sswallace	struct open_args cup;
21511394Sswallace	caddr_t sg = stackgap_init();
21611394Sswallace
21711394Sswallace	CHECKALTCREAT(p, &sg, SCARG(uap, path));
21811394Sswallace	SCARG(&cup, path) = SCARG(uap, path);
21911394Sswallace	SCARG(&cup, mode) = SCARG(uap, mode);
22011394Sswallace	SCARG(&cup, flags) = O_WRONLY | O_CREAT | O_TRUNC;
22111394Sswallace	return open(p, &cup, retval);
22211394Sswallace}
22311394Sswallace
22411394Sswallaceint
22511394Sswallaceibcs2_access(p, uap, retval)
22611394Sswallace        struct proc *p;
22711394Sswallace        struct ibcs2_access_args *uap;
22811394Sswallace        int *retval;
22911394Sswallace{
23011394Sswallace        struct access_args cup;
23111394Sswallace        caddr_t sg = stackgap_init();
23211394Sswallace
23311394Sswallace        CHECKALTEXIST(p, &sg, SCARG(uap, path));
23411394Sswallace        SCARG(&cup, path) = SCARG(uap, path);
23511394Sswallace        SCARG(&cup, flags) = SCARG(uap, flags);
23611394Sswallace        return access(p, &cup, retval);
23711394Sswallace}
23811394Sswallace
23911394Sswallaceint
24011394Sswallaceibcs2_fcntl(p, uap, retval)
24111394Sswallace	struct proc *p;
24211394Sswallace	struct ibcs2_fcntl_args *uap;
24311394Sswallace	int *retval;
24411394Sswallace{
24511394Sswallace	int error;
24611394Sswallace	struct fcntl_args fa;
24711394Sswallace	struct flock *flp;
24811394Sswallace	struct ibcs2_flock ifl;
24911394Sswallace
25011394Sswallace	switch(SCARG(uap, cmd)) {
25111394Sswallace	case IBCS2_F_DUPFD:
25211394Sswallace		SCARG(&fa, fd) = SCARG(uap, fd);
25311394Sswallace		SCARG(&fa, cmd) = F_DUPFD;
25412218Sbde		SCARG(&fa, arg) = (/* XXX */ int)SCARG(uap, arg);
25511394Sswallace		return fcntl(p, &fa, retval);
25611394Sswallace	case IBCS2_F_GETFD:
25711394Sswallace		SCARG(&fa, fd) = SCARG(uap, fd);
25811394Sswallace		SCARG(&fa, cmd) = F_GETFD;
25912218Sbde		SCARG(&fa, arg) = (/* XXX */ int)SCARG(uap, arg);
26011394Sswallace		return fcntl(p, &fa, retval);
26111394Sswallace	case IBCS2_F_SETFD:
26211394Sswallace		SCARG(&fa, fd) = SCARG(uap, fd);
26311394Sswallace		SCARG(&fa, cmd) = F_SETFD;
26412218Sbde		SCARG(&fa, arg) = (/* XXX */ int)SCARG(uap, arg);
26511394Sswallace		return fcntl(p, &fa, retval);
26611394Sswallace	case IBCS2_F_GETFL:
26711394Sswallace		SCARG(&fa, fd) = SCARG(uap, fd);
26811394Sswallace		SCARG(&fa, cmd) = F_GETFL;
26912218Sbde		SCARG(&fa, arg) = (/* XXX */ int)SCARG(uap, arg);
27011394Sswallace		error = fcntl(p, &fa, retval);
27111394Sswallace		if (error)
27211394Sswallace			return error;
27311394Sswallace		*retval = oflags2ioflags(*retval);
27411394Sswallace		return error;
27511394Sswallace	case IBCS2_F_SETFL:
27611394Sswallace		SCARG(&fa, fd) = SCARG(uap, fd);
27711394Sswallace		SCARG(&fa, cmd) = F_SETFL;
27812218Sbde		SCARG(&fa, arg) = (/* XXX */ int)
27912218Sbde				  ioflags2oflags((int)SCARG(uap, arg));
28011394Sswallace		return fcntl(p, &fa, retval);
28111394Sswallace
28211394Sswallace	case IBCS2_F_GETLK:
28311394Sswallace	    {
28411394Sswallace		caddr_t sg = stackgap_init();
28511394Sswallace		flp = stackgap_alloc(&sg, sizeof(*flp));
28611394Sswallace		error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&ifl,
28711394Sswallace			       ibcs2_flock_len);
28811394Sswallace		if (error)
28911394Sswallace			return error;
29011394Sswallace		cvt_iflock2flock(&ifl, flp);
29111394Sswallace		SCARG(&fa, fd) = SCARG(uap, fd);
29211394Sswallace		SCARG(&fa, cmd) = F_GETLK;
29312218Sbde		SCARG(&fa, arg) = (/* XXX */ int)flp;
29411394Sswallace		error = fcntl(p, &fa, retval);
29511394Sswallace		if (error)
29611394Sswallace			return error;
29711394Sswallace		cvt_flock2iflock(flp, &ifl);
29811394Sswallace		return copyout((caddr_t)&ifl, (caddr_t)SCARG(uap, arg),
29911394Sswallace			       ibcs2_flock_len);
30011394Sswallace	    }
30111394Sswallace
30211394Sswallace	case IBCS2_F_SETLK:
30311394Sswallace	    {
30411394Sswallace		caddr_t sg = stackgap_init();
30511394Sswallace		flp = stackgap_alloc(&sg, sizeof(*flp));
30611394Sswallace		error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&ifl,
30711394Sswallace			       ibcs2_flock_len);
30811394Sswallace		if (error)
30911394Sswallace			return error;
31011394Sswallace		cvt_iflock2flock(&ifl, flp);
31111394Sswallace		SCARG(&fa, fd) = SCARG(uap, fd);
31211394Sswallace		SCARG(&fa, cmd) = F_SETLK;
31312218Sbde		SCARG(&fa, arg) = (/* XXX */ int)flp;
31411397Sswallace
31511394Sswallace		return fcntl(p, &fa, retval);
31611394Sswallace	    }
31711394Sswallace
31811394Sswallace	case IBCS2_F_SETLKW:
31911394Sswallace	    {
32011394Sswallace		caddr_t sg = stackgap_init();
32111394Sswallace		flp = stackgap_alloc(&sg, sizeof(*flp));
32211394Sswallace		error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&ifl,
32311394Sswallace			       ibcs2_flock_len);
32411394Sswallace		if (error)
32511394Sswallace			return error;
32611394Sswallace		cvt_iflock2flock(&ifl, flp);
32711394Sswallace		SCARG(&fa, fd) = SCARG(uap, fd);
32811394Sswallace		SCARG(&fa, cmd) = F_SETLKW;
32912218Sbde		SCARG(&fa, arg) = (/* XXX */ int)flp;
33011394Sswallace		return fcntl(p, &fa, retval);
33111394Sswallace	    }
33211394Sswallace	}
33311394Sswallace	return ENOSYS;
33411394Sswallace}
335