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