svr4_fcntl.c revision 83366
143412Snewton/*
243412Snewton * Copyright (c) 1998 Mark Newton
343412Snewton * Copyright (c) 1994, 1997 Christos Zoulas.
443412Snewton * All rights reserved.
543412Snewton *
643412Snewton * Redistribution and use in source and binary forms, with or without
743412Snewton * modification, are permitted provided that the following conditions
843412Snewton * are met:
943412Snewton * 1. Redistributions of source code must retain the above copyright
1043412Snewton *    notice, this list of conditions and the following disclaimer.
1143412Snewton * 2. Redistributions in binary form must reproduce the above copyright
1243412Snewton *    notice, this list of conditions and the following disclaimer in the
1343412Snewton *    documentation and/or other materials provided with the distribution.
1443412Snewton * 3. All advertising materials mentioning features or use of this software
1543412Snewton *    must display the following acknowledgement:
1643412Snewton *	This product includes software developed by Christos Zoulas.
1743412Snewton * 4. The name of the author may not be used to endorse or promote products
1843412Snewton *    derived from this software without specific prior written permission.
1943412Snewton *
2043412Snewton * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2143412Snewton * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2243412Snewton * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2343412Snewton * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2443412Snewton * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2543412Snewton * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2643412Snewton * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2743412Snewton * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2843412Snewton * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2943412Snewton * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3049267Snewton *
3150477Speter * $FreeBSD: head/sys/compat/svr4/svr4_fcntl.c 83366 2001-09-12 08:38:13Z julian $
3243412Snewton */
3343412Snewton#include <sys/param.h>
3443412Snewton#include <sys/systm.h>
3543412Snewton#include <sys/file.h>
3643412Snewton#include <sys/filedesc.h>
3743412Snewton/*#include <sys/ioctl.h>*/
3876166Smarkm#include <sys/lock.h>
3943412Snewton#include <sys/mount.h>
4076166Smarkm#include <sys/mutex.h>
4176166Smarkm#include <sys/namei.h>
4276166Smarkm#include <sys/proc.h>
4376166Smarkm#include <sys/stat.h>
4476166Smarkm#include <sys/unistd.h>
4543412Snewton#include <sys/vnode.h>
4643412Snewton
4743412Snewton#include <sys/sysproto.h>
4843412Snewton
4965302Sobrien#include <compat/svr4/svr4.h>
5065302Sobrien#include <compat/svr4/svr4_types.h>
5165302Sobrien#include <compat/svr4/svr4_signal.h>
5265302Sobrien#include <compat/svr4/svr4_proto.h>
5365302Sobrien#include <compat/svr4/svr4_util.h>
5465302Sobrien#include <compat/svr4/svr4_fcntl.h>
5543412Snewton
5643412Snewtonstatic int svr4_to_bsd_flags __P((int));
5743412Snewtonstatic u_long svr4_to_bsd_cmd __P((u_long));
5883366Sjulianstatic int fd_revoke __P((struct thread *, int));
5983366Sjulianstatic int fd_truncate __P((struct thread *, int, struct flock *));
6043412Snewtonstatic int bsd_to_svr4_flags __P((int));
6143412Snewtonstatic void bsd_to_svr4_flock __P((struct flock *, struct svr4_flock *));
6243412Snewtonstatic void svr4_to_bsd_flock __P((struct svr4_flock *, struct flock *));
6343412Snewtonstatic void bsd_to_svr4_flock64 __P((struct flock *, struct svr4_flock64 *));
6443412Snewtonstatic void svr4_to_bsd_flock64 __P((struct svr4_flock64 *, struct flock *));
6543412Snewton
6643412Snewtonstatic u_long
6743412Snewtonsvr4_to_bsd_cmd(cmd)
6843412Snewton	u_long	cmd;
6943412Snewton{
7043412Snewton	switch (cmd) {
7143412Snewton	case SVR4_F_DUPFD:
7243412Snewton		return F_DUPFD;
7343412Snewton	case SVR4_F_GETFD:
7443412Snewton		return F_GETFD;
7543412Snewton	case SVR4_F_SETFD:
7643412Snewton		return F_SETFD;
7743412Snewton	case SVR4_F_GETFL:
7843412Snewton		return F_GETFL;
7943412Snewton	case SVR4_F_SETFL:
8043412Snewton		return F_SETFL;
8143412Snewton	case SVR4_F_GETLK:
8243412Snewton		return F_GETLK;
8343412Snewton	case SVR4_F_SETLK:
8443412Snewton		return F_SETLK;
8543412Snewton	case SVR4_F_SETLKW:
8643412Snewton		return F_SETLKW;
8743412Snewton	default:
8843412Snewton		return -1;
8943412Snewton	}
9043412Snewton}
9143412Snewton
9243412Snewtonstatic int
9343412Snewtonsvr4_to_bsd_flags(l)
9443412Snewton	int	l;
9543412Snewton{
9643412Snewton	int	r = 0;
9743412Snewton	r |= (l & SVR4_O_RDONLY) ? O_RDONLY : 0;
9843412Snewton	r |= (l & SVR4_O_WRONLY) ? O_WRONLY : 0;
9943412Snewton	r |= (l & SVR4_O_RDWR) ? O_RDWR : 0;
10043412Snewton	r |= (l & SVR4_O_NDELAY) ? O_NONBLOCK : 0;
10143412Snewton	r |= (l & SVR4_O_APPEND) ? O_APPEND : 0;
10243412Snewton	r |= (l & SVR4_O_SYNC) ? O_FSYNC : 0;
10343412Snewton	r |= (l & SVR4_O_NONBLOCK) ? O_NONBLOCK : 0;
10443412Snewton	r |= (l & SVR4_O_PRIV) ? O_EXLOCK : 0;
10543412Snewton	r |= (l & SVR4_O_CREAT) ? O_CREAT : 0;
10643412Snewton	r |= (l & SVR4_O_TRUNC) ? O_TRUNC : 0;
10743412Snewton	r |= (l & SVR4_O_EXCL) ? O_EXCL : 0;
10843412Snewton	r |= (l & SVR4_O_NOCTTY) ? O_NOCTTY : 0;
10943412Snewton	return r;
11043412Snewton}
11143412Snewton
11243412Snewtonstatic int
11343412Snewtonbsd_to_svr4_flags(l)
11443412Snewton	int	l;
11543412Snewton{
11643412Snewton	int	r = 0;
11743412Snewton	r |= (l & O_RDONLY) ? SVR4_O_RDONLY : 0;
11843412Snewton	r |= (l & O_WRONLY) ? SVR4_O_WRONLY : 0;
11943412Snewton	r |= (l & O_RDWR) ? SVR4_O_RDWR : 0;
12043412Snewton	r |= (l & O_NDELAY) ? SVR4_O_NONBLOCK : 0;
12143412Snewton	r |= (l & O_APPEND) ? SVR4_O_APPEND : 0;
12243412Snewton	r |= (l & O_FSYNC) ? SVR4_O_SYNC : 0;
12343412Snewton	r |= (l & O_NONBLOCK) ? SVR4_O_NONBLOCK : 0;
12443412Snewton	r |= (l & O_EXLOCK) ? SVR4_O_PRIV : 0;
12543412Snewton	r |= (l & O_CREAT) ? SVR4_O_CREAT : 0;
12643412Snewton	r |= (l & O_TRUNC) ? SVR4_O_TRUNC : 0;
12743412Snewton	r |= (l & O_EXCL) ? SVR4_O_EXCL : 0;
12843412Snewton	r |= (l & O_NOCTTY) ? SVR4_O_NOCTTY : 0;
12943412Snewton	return r;
13043412Snewton}
13143412Snewton
13243412Snewton
13343412Snewtonstatic void
13443412Snewtonbsd_to_svr4_flock(iflp, oflp)
13543412Snewton	struct flock		*iflp;
13643412Snewton	struct svr4_flock	*oflp;
13743412Snewton{
13843412Snewton	switch (iflp->l_type) {
13943412Snewton	case F_RDLCK:
14043412Snewton		oflp->l_type = SVR4_F_RDLCK;
14143412Snewton		break;
14243412Snewton	case F_WRLCK:
14343412Snewton		oflp->l_type = SVR4_F_WRLCK;
14443412Snewton		break;
14543412Snewton	case F_UNLCK:
14643412Snewton		oflp->l_type = SVR4_F_UNLCK;
14743412Snewton		break;
14843412Snewton	default:
14943412Snewton		oflp->l_type = -1;
15043412Snewton		break;
15143412Snewton	}
15243412Snewton
15343412Snewton	oflp->l_whence = (short) iflp->l_whence;
15443412Snewton	oflp->l_start = (svr4_off_t) iflp->l_start;
15543412Snewton	oflp->l_len = (svr4_off_t) iflp->l_len;
15643412Snewton	oflp->l_sysid = 0;
15743412Snewton	oflp->l_pid = (svr4_pid_t) iflp->l_pid;
15843412Snewton}
15943412Snewton
16043412Snewton
16143412Snewtonstatic void
16243412Snewtonsvr4_to_bsd_flock(iflp, oflp)
16343412Snewton	struct svr4_flock	*iflp;
16443412Snewton	struct flock		*oflp;
16543412Snewton{
16643412Snewton	switch (iflp->l_type) {
16743412Snewton	case SVR4_F_RDLCK:
16843412Snewton		oflp->l_type = F_RDLCK;
16943412Snewton		break;
17043412Snewton	case SVR4_F_WRLCK:
17143412Snewton		oflp->l_type = F_WRLCK;
17243412Snewton		break;
17343412Snewton	case SVR4_F_UNLCK:
17443412Snewton		oflp->l_type = F_UNLCK;
17543412Snewton		break;
17643412Snewton	default:
17743412Snewton		oflp->l_type = -1;
17843412Snewton		break;
17943412Snewton	}
18043412Snewton
18143412Snewton	oflp->l_whence = iflp->l_whence;
18243412Snewton	oflp->l_start = (off_t) iflp->l_start;
18343412Snewton	oflp->l_len = (off_t) iflp->l_len;
18443412Snewton	oflp->l_pid = (pid_t) iflp->l_pid;
18543412Snewton
18643412Snewton}
18743412Snewton
18843412Snewtonstatic void
18943412Snewtonbsd_to_svr4_flock64(iflp, oflp)
19043412Snewton	struct flock		*iflp;
19143412Snewton	struct svr4_flock64	*oflp;
19243412Snewton{
19343412Snewton	switch (iflp->l_type) {
19443412Snewton	case F_RDLCK:
19543412Snewton		oflp->l_type = SVR4_F_RDLCK;
19643412Snewton		break;
19743412Snewton	case F_WRLCK:
19843412Snewton		oflp->l_type = SVR4_F_WRLCK;
19943412Snewton		break;
20043412Snewton	case F_UNLCK:
20143412Snewton		oflp->l_type = SVR4_F_UNLCK;
20243412Snewton		break;
20343412Snewton	default:
20443412Snewton		oflp->l_type = -1;
20543412Snewton		break;
20643412Snewton	}
20743412Snewton
20843412Snewton	oflp->l_whence = (short) iflp->l_whence;
20943412Snewton	oflp->l_start = (svr4_off64_t) iflp->l_start;
21043412Snewton	oflp->l_len = (svr4_off64_t) iflp->l_len;
21143412Snewton	oflp->l_sysid = 0;
21243412Snewton	oflp->l_pid = (svr4_pid_t) iflp->l_pid;
21343412Snewton}
21443412Snewton
21543412Snewton
21643412Snewtonstatic void
21743412Snewtonsvr4_to_bsd_flock64(iflp, oflp)
21843412Snewton	struct svr4_flock64	*iflp;
21943412Snewton	struct flock		*oflp;
22043412Snewton{
22143412Snewton	switch (iflp->l_type) {
22243412Snewton	case SVR4_F_RDLCK:
22343412Snewton		oflp->l_type = F_RDLCK;
22443412Snewton		break;
22543412Snewton	case SVR4_F_WRLCK:
22643412Snewton		oflp->l_type = F_WRLCK;
22743412Snewton		break;
22843412Snewton	case SVR4_F_UNLCK:
22943412Snewton		oflp->l_type = F_UNLCK;
23043412Snewton		break;
23143412Snewton	default:
23243412Snewton		oflp->l_type = -1;
23343412Snewton		break;
23443412Snewton	}
23543412Snewton
23643412Snewton	oflp->l_whence = iflp->l_whence;
23743412Snewton	oflp->l_start = (off_t) iflp->l_start;
23843412Snewton	oflp->l_len = (off_t) iflp->l_len;
23943412Snewton	oflp->l_pid = (pid_t) iflp->l_pid;
24043412Snewton
24143412Snewton}
24243412Snewton
24343412Snewton
24443412Snewtonstatic int
24583366Sjulianfd_revoke(td, fd)
24683366Sjulian	struct thread *td;
24743412Snewton	int fd;
24843412Snewton{
24983366Sjulian	struct filedesc *fdp = td->td_proc->p_fd;
25043412Snewton	struct file *fp;
25143412Snewton	struct vnode *vp;
25262976Smckusick	struct mount *mp;
25343412Snewton	struct vattr vattr;
25443412Snewton	int error, *retval;
25543412Snewton
25683366Sjulian	retval = td->td_retval;
25743412Snewton	if ((u_int)fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL)
25843412Snewton		return EBADF;
25943412Snewton
26054492Snewton	if (fp->f_type != DTYPE_VNODE)
26143412Snewton		return EINVAL;
26243412Snewton
26354492Snewton	vp = (struct vnode *) fp->f_data;
26443412Snewton
26543412Snewton	if (vp->v_type != VCHR && vp->v_type != VBLK) {
26643412Snewton		error = EINVAL;
26743412Snewton		goto out;
26843412Snewton	}
26943412Snewton
27083366Sjulian	if ((error = VOP_GETATTR(vp, &vattr, td->td_proc->p_ucred, td)) != 0)
27143412Snewton		goto out;
27243412Snewton
27383366Sjulian	if (td->td_proc->p_ucred->cr_uid != vattr.va_uid &&
27483366Sjulian	    (error = suser_td(td)) != 0)
27543412Snewton		goto out;
27643412Snewton
27762976Smckusick	if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
27862976Smckusick		goto out;
27950405Sphk	if (vcount(vp) > 1)
28043412Snewton		VOP_REVOKE(vp, REVOKEALL);
28162976Smckusick	vn_finished_write(mp);
28243412Snewtonout:
28343412Snewton	vrele(vp);
28443412Snewton	return error;
28543412Snewton}
28643412Snewton
28743412Snewton
28843412Snewtonstatic int
28983366Sjulianfd_truncate(td, fd, flp)
29083366Sjulian	struct thread *td;
29143412Snewton	int fd;
29243412Snewton	struct flock *flp;
29343412Snewton{
29483366Sjulian	struct filedesc *fdp = td->td_proc->p_fd;
29543412Snewton	struct file *fp;
29643412Snewton	off_t start, length;
29743412Snewton	struct vnode *vp;
29843412Snewton	struct vattr vattr;
29943412Snewton	int error, *retval;
30043412Snewton	struct ftruncate_args ft;
30143412Snewton
30283366Sjulian	retval = td->td_retval;
30343412Snewton
30443412Snewton	/*
30543412Snewton	 * We only support truncating the file.
30643412Snewton	 */
30743412Snewton	if ((u_int)fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL)
30843412Snewton		return EBADF;
30943412Snewton
31043412Snewton	vp = (struct vnode *)fp->f_data;
31143412Snewton	if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO)
31243412Snewton		return ESPIPE;
31343412Snewton
31483366Sjulian	if ((error = VOP_GETATTR(vp, &vattr, td->td_proc->p_ucred, td)) != 0)
31543412Snewton		return error;
31643412Snewton
31743412Snewton	length = vattr.va_size;
31843412Snewton
31943412Snewton	switch (flp->l_whence) {
32043412Snewton	case SEEK_CUR:
32143412Snewton		start = fp->f_offset + flp->l_start;
32243412Snewton		break;
32343412Snewton
32443412Snewton	case SEEK_END:
32543412Snewton		start = flp->l_start + length;
32643412Snewton		break;
32743412Snewton
32843412Snewton	case SEEK_SET:
32943412Snewton		start = flp->l_start;
33043412Snewton		break;
33143412Snewton
33243412Snewton	default:
33343412Snewton		return EINVAL;
33443412Snewton	}
33543412Snewton
33643412Snewton	if (start + flp->l_len < length) {
33743412Snewton		/* We don't support free'ing in the middle of the file */
33843412Snewton		return EINVAL;
33943412Snewton	}
34043412Snewton
34143412Snewton	SCARG(&ft, fd) = fd;
34243412Snewton	SCARG(&ft, length) = start;
34343412Snewton
34483366Sjulian	return ftruncate(td, &ft);
34543412Snewton}
34643412Snewton
34743412Snewtonint
34883366Sjuliansvr4_sys_open(td, uap)
34983366Sjulian	register struct thread *td;
35043412Snewton	struct svr4_sys_open_args *uap;
35143412Snewton{
35283366Sjulian	struct proc *p = td->td_proc;
35343412Snewton	int			error, retval;
35443412Snewton	struct open_args	cup;
35543412Snewton
35643412Snewton	caddr_t sg = stackgap_init();
35783366Sjulian	CHECKALTEXIST(td, &sg, SCARG(uap, path));
35843412Snewton
35943412Snewton	(&cup)->path = uap->path;
36043412Snewton	(&cup)->flags = svr4_to_bsd_flags(uap->flags);
36143412Snewton	(&cup)->mode = uap->mode;
36283366Sjulian	error = open(td, &cup);
36343412Snewton
36443412Snewton	if (error) {
36543412Snewton	  /*	        uprintf("svr4_open(%s, 0x%0x, 0%o): %d\n", uap->path,
36643412Snewton			uap->flags, uap->mode, error);*/
36743412Snewton		return error;
36843412Snewton	}
36943412Snewton
37083366Sjulian	retval = td->td_retval[0];
37143412Snewton
37271454Sjhb	PROC_LOCK(p);
37343412Snewton	if (!(SCARG(&cup, flags) & O_NOCTTY) && SESS_LEADER(p) &&
37483366Sjulian	    !(td->td_proc->p_flag & P_CONTROLT)) {
37543412Snewton#if defined(NOTYET)
37683366Sjulian		struct filedesc	*fdp = td->td_proc->p_fd;
37743412Snewton		struct file	*fp = fdp->fd_ofiles[retval];
37843412Snewton
37971454Sjhb		PROC_UNLOCK(p);
38043412Snewton		/* ignore any error, just give it a try */
38143412Snewton		if (fp->f_type == DTYPE_VNODE)
38283366Sjulian			fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td);
38371454Sjhb	} else
38471454Sjhb		PROC_UNLOCK(p);
38571454Sjhb#else
38671454Sjhb	}
38771454Sjhb	PROC_UNLOCK(p);
38843412Snewton#endif
38943412Snewton	return error;
39043412Snewton}
39143412Snewton
39243412Snewtonint
39383366Sjuliansvr4_sys_open64(td, uap)
39483366Sjulian	register struct thread *td;
39543412Snewton	struct svr4_sys_open64_args *uap;
39643412Snewton{
39783366Sjulian	return svr4_sys_open(td, (struct svr4_sys_open_args *)uap);
39843412Snewton}
39943412Snewton
40043412Snewtonint
40183366Sjuliansvr4_sys_creat(td, uap)
40283366Sjulian	register struct thread *td;
40343412Snewton	struct svr4_sys_creat_args *uap;
40443412Snewton{
40543412Snewton	struct open_args cup;
40643412Snewton
40743412Snewton	caddr_t sg = stackgap_init();
40883366Sjulian	CHECKALTEXIST(td, &sg, SCARG(uap, path));
40943412Snewton
41043412Snewton	SCARG(&cup, path) = SCARG(uap, path);
41143412Snewton	SCARG(&cup, mode) = SCARG(uap, mode);
41243412Snewton	SCARG(&cup, flags) = O_WRONLY | O_CREAT | O_TRUNC;
41343412Snewton
41483366Sjulian	return open(td, &cup);
41543412Snewton}
41643412Snewton
41743412Snewtonint
41883366Sjuliansvr4_sys_creat64(td, uap)
41983366Sjulian	register struct thread *td;
42043412Snewton	struct svr4_sys_creat64_args *uap;
42143412Snewton{
42283366Sjulian	return svr4_sys_creat(td, (struct svr4_sys_creat_args *)uap);
42343412Snewton}
42443412Snewton
42543412Snewtonint
42683366Sjuliansvr4_sys_llseek(td, uap)
42783366Sjulian	register struct thread *td;
42871454Sjhb	struct svr4_sys_llseek_args *uap;
42943412Snewton{
43043412Snewton	struct lseek_args ap;
43143412Snewton
43243412Snewton	SCARG(&ap, fd) = SCARG(uap, fd);
43343412Snewton
43443412Snewton#if BYTE_ORDER == BIG_ENDIAN
43571454Sjhb	SCARG(&ap, offset) = (((u_int64_t) SCARG(uap, offset1)) << 32) |
43643412Snewton		SCARG(uap, offset2);
43743412Snewton#else
43871454Sjhb	SCARG(&ap, offset) = (((u_int64_t) SCARG(uap, offset2)) << 32) |
43943412Snewton		SCARG(uap, offset1);
44043412Snewton#endif
44143412Snewton	SCARG(&ap, whence) = SCARG(uap, whence);
44243412Snewton
44383366Sjulian	return lseek(td, &ap);
44443412Snewton}
44543412Snewton
44643412Snewtonint
44783366Sjuliansvr4_sys_access(td, uap)
44883366Sjulian	register struct thread *td;
44943412Snewton	struct svr4_sys_access_args *uap;
45043412Snewton{
45143412Snewton	struct access_args cup;
45243412Snewton	int *retval;
45343412Snewton
45443412Snewton	caddr_t sg = stackgap_init();
45583366Sjulian	CHECKALTEXIST(td, &sg, SCARG(uap, path));
45643412Snewton
45783366Sjulian	retval = td->td_retval;
45843412Snewton
45943412Snewton	SCARG(&cup, path) = SCARG(uap, path);
46043412Snewton	SCARG(&cup, flags) = SCARG(uap, flags);
46143412Snewton
46283366Sjulian	return access(td, &cup);
46343412Snewton}
46443412Snewton
46543412Snewton#if defined(NOTYET)
46643412Snewtonint
46783366Sjuliansvr4_sys_pread(td, uap)
46883366Sjulian	register struct thread *td;
46943412Snewton	struct svr4_sys_pread_args *uap;
47043412Snewton{
47143412Snewton	struct pread_args pra;
47243412Snewton
47343412Snewton	/*
47443412Snewton	 * Just translate the args structure and call the NetBSD
47543412Snewton	 * pread(2) system call (offset type is 64-bit in NetBSD).
47643412Snewton	 */
47743412Snewton	SCARG(&pra, fd) = SCARG(uap, fd);
47843412Snewton	SCARG(&pra, buf) = SCARG(uap, buf);
47943412Snewton	SCARG(&pra, nbyte) = SCARG(uap, nbyte);
48043412Snewton	SCARG(&pra, offset) = SCARG(uap, off);
48143412Snewton
48283366Sjulian	return pread(td, &pra);
48343412Snewton}
48443412Snewton#endif
48543412Snewton
48643412Snewton#if defined(NOTYET)
48743412Snewtonint
48883366Sjuliansvr4_sys_pread64(td, v, retval)
48983366Sjulian	register struct thread *td;
49043412Snewton	void *v;
49143412Snewton	register_t *retval;
49243412Snewton{
49343412Snewton
49443412Snewton	struct svr4_sys_pread64_args *uap = v;
49543412Snewton	struct sys_pread_args pra;
49643412Snewton
49743412Snewton	/*
49843412Snewton	 * Just translate the args structure and call the NetBSD
49943412Snewton	 * pread(2) system call (offset type is 64-bit in NetBSD).
50043412Snewton	 */
50143412Snewton	SCARG(&pra, fd) = SCARG(uap, fd);
50243412Snewton	SCARG(&pra, buf) = SCARG(uap, buf);
50343412Snewton	SCARG(&pra, nbyte) = SCARG(uap, nbyte);
50443412Snewton	SCARG(&pra, offset) = SCARG(uap, off);
50543412Snewton
50683366Sjulian	return (sys_pread(td, &pra, retval));
50743412Snewton}
50843412Snewton#endif /* NOTYET */
50943412Snewton
51043412Snewton#if defined(NOTYET)
51143412Snewtonint
51283366Sjuliansvr4_sys_pwrite(td, uap)
51383366Sjulian	register struct thread *td;
51443412Snewton	struct svr4_sys_pwrite_args *uap;
51543412Snewton{
51643412Snewton	struct pwrite_args pwa;
51743412Snewton
51843412Snewton	/*
51943412Snewton	 * Just translate the args structure and call the NetBSD
52043412Snewton	 * pwrite(2) system call (offset type is 64-bit in NetBSD).
52143412Snewton	 */
52243412Snewton	SCARG(&pwa, fd) = SCARG(uap, fd);
52343412Snewton	SCARG(&pwa, buf) = SCARG(uap, buf);
52443412Snewton	SCARG(&pwa, nbyte) = SCARG(uap, nbyte);
52543412Snewton	SCARG(&pwa, offset) = SCARG(uap, off);
52643412Snewton
52783366Sjulian	return pwrite(td, &pwa);
52843412Snewton}
52943412Snewton#endif
53043412Snewton
53143412Snewton#if defined(NOTYET)
53243412Snewtonint
53383366Sjuliansvr4_sys_pwrite64(td, v, retval)
53483366Sjulian	register struct thread *td;
53543412Snewton	void *v;
53643412Snewton	register_t *retval;
53743412Snewton{
53843412Snewton	struct svr4_sys_pwrite64_args *uap = v;
53943412Snewton	struct sys_pwrite_args pwa;
54043412Snewton
54143412Snewton	/*
54243412Snewton	 * Just translate the args structure and call the NetBSD
54343412Snewton	 * pwrite(2) system call (offset type is 64-bit in NetBSD).
54443412Snewton	 */
54543412Snewton	SCARG(&pwa, fd) = SCARG(uap, fd);
54643412Snewton	SCARG(&pwa, buf) = SCARG(uap, buf);
54743412Snewton	SCARG(&pwa, nbyte) = SCARG(uap, nbyte);
54843412Snewton	SCARG(&pwa, offset) = SCARG(uap, off);
54943412Snewton
55083366Sjulian	return (sys_pwrite(td, &pwa, retval));
55143412Snewton}
55243412Snewton#endif /* NOTYET */
55343412Snewton
55443412Snewtonint
55583366Sjuliansvr4_sys_fcntl(td, uap)
55683366Sjulian	register struct thread *td;
55743412Snewton	struct svr4_sys_fcntl_args *uap;
55843412Snewton{
55943412Snewton	int				error;
56043412Snewton	struct fcntl_args		fa;
56143412Snewton	int                             *retval;
56243412Snewton
56383366Sjulian	retval = td->td_retval;
56443412Snewton
56543412Snewton	SCARG(&fa, fd) = SCARG(uap, fd);
56643412Snewton	SCARG(&fa, cmd) = svr4_to_bsd_cmd(SCARG(uap, cmd));
56743412Snewton
56843412Snewton	switch (SCARG(&fa, cmd)) {
56943412Snewton	case F_DUPFD:
57043412Snewton	case F_GETFD:
57143412Snewton	case F_SETFD:
57243412Snewton		SCARG(&fa, arg) = (long) SCARG(uap, arg);
57383366Sjulian		return fcntl(td, &fa);
57443412Snewton
57543412Snewton	case F_GETFL:
57643412Snewton		SCARG(&fa, arg) = (long) SCARG(uap, arg);
57783366Sjulian		error = fcntl(td, &fa);
57843412Snewton		if (error)
57943412Snewton			return error;
58043412Snewton		*retval = bsd_to_svr4_flags(*retval);
58143412Snewton		return error;
58243412Snewton
58343412Snewton	case F_SETFL:
58443412Snewton		{
58543412Snewton			/*
58643412Snewton			 * we must save the O_ASYNC flag, as that is
58743412Snewton			 * handled by ioctl(_, I_SETSIG, _) emulation.
58843412Snewton			 */
58943412Snewton			long cmd;
59043412Snewton			int flags;
59143412Snewton
59280114Sassar			DPRINTF(("Setting flags %p\n", SCARG(uap, arg)));
59343412Snewton			cmd = SCARG(&fa, cmd); /* save it for a while */
59443412Snewton
59543412Snewton			SCARG(&fa, cmd) = F_GETFL;
59683366Sjulian			if ((error = fcntl(td, &fa)) != 0)
59743412Snewton				return error;
59843412Snewton			flags = *retval;
59943412Snewton			flags &= O_ASYNC;
60043412Snewton			flags |= svr4_to_bsd_flags((u_long) SCARG(uap, arg));
60143412Snewton			SCARG(&fa, cmd) = cmd;
60243412Snewton			SCARG(&fa, arg) = (long) flags;
60383366Sjulian			return fcntl(td, &fa);
60443412Snewton		}
60543412Snewton
60643412Snewton	case F_GETLK:
60743412Snewton	case F_SETLK:
60843412Snewton	case F_SETLKW:
60943412Snewton		{
61043412Snewton			struct svr4_flock	 ifl;
61143412Snewton			struct flock		*flp, fl;
61243412Snewton			caddr_t sg = stackgap_init();
61343412Snewton
61443412Snewton			flp = stackgap_alloc(&sg, sizeof(struct flock));
61543412Snewton			SCARG(&fa, arg) = (long) flp;
61643412Snewton
61743412Snewton			error = copyin(SCARG(uap, arg), &ifl, sizeof ifl);
61843412Snewton			if (error)
61943412Snewton				return error;
62043412Snewton
62143412Snewton			svr4_to_bsd_flock(&ifl, &fl);
62243412Snewton
62343412Snewton			error = copyout(&fl, flp, sizeof fl);
62443412Snewton			if (error)
62543412Snewton				return error;
62643412Snewton
62783366Sjulian			error = fcntl(td, &fa);
62843412Snewton			if (error || SCARG(&fa, cmd) != F_GETLK)
62943412Snewton				return error;
63043412Snewton
63143412Snewton			error = copyin(flp, &fl, sizeof fl);
63243412Snewton			if (error)
63343412Snewton				return error;
63443412Snewton
63543412Snewton			bsd_to_svr4_flock(&fl, &ifl);
63643412Snewton
63743412Snewton			return copyout(&ifl, SCARG(uap, arg), sizeof ifl);
63843412Snewton		}
63943412Snewton	case -1:
64043412Snewton		switch (SCARG(uap, cmd)) {
64143412Snewton		case SVR4_F_DUP2FD:
64243412Snewton			{
64343412Snewton				struct dup2_args du;
64443412Snewton
64543412Snewton				SCARG(&du, from) = SCARG(uap, fd);
64643412Snewton				SCARG(&du, to) = (int)SCARG(uap, arg);
64783366Sjulian				error = dup2(td, &du);
64843412Snewton				if (error)
64943412Snewton					return error;
65043412Snewton				*retval = SCARG(&du, to);
65143412Snewton				return 0;
65243412Snewton			}
65343412Snewton
65443412Snewton		case SVR4_F_FREESP:
65543412Snewton			{
65643412Snewton				struct svr4_flock	 ifl;
65743412Snewton				struct flock		 fl;
65843412Snewton
65943412Snewton				error = copyin(SCARG(uap, arg), &ifl,
66043412Snewton				    sizeof ifl);
66143412Snewton				if (error)
66243412Snewton					return error;
66343412Snewton				svr4_to_bsd_flock(&ifl, &fl);
66483366Sjulian				return fd_truncate(td, SCARG(uap, fd), &fl);
66543412Snewton			}
66643412Snewton
66743412Snewton		case SVR4_F_GETLK64:
66843412Snewton		case SVR4_F_SETLK64:
66943412Snewton		case SVR4_F_SETLKW64:
67043412Snewton			{
67143412Snewton				struct svr4_flock64	 ifl;
67243412Snewton				struct flock		*flp, fl;
67343412Snewton				caddr_t sg = stackgap_init();
67443412Snewton
67543412Snewton				flp = stackgap_alloc(&sg, sizeof(struct flock));
67643412Snewton				SCARG(&fa, arg) = (long) flp;
67743412Snewton
67843412Snewton				error = copyin(SCARG(uap, arg), &ifl,
67943412Snewton				    sizeof ifl);
68043412Snewton				if (error)
68143412Snewton					return error;
68243412Snewton
68343412Snewton				svr4_to_bsd_flock64(&ifl, &fl);
68443412Snewton
68543412Snewton				error = copyout(&fl, flp, sizeof fl);
68643412Snewton				if (error)
68743412Snewton					return error;
68843412Snewton
68983366Sjulian				error = fcntl(td, &fa);
69043412Snewton				if (error || SCARG(&fa, cmd) != F_GETLK)
69143412Snewton					return error;
69243412Snewton
69343412Snewton				error = copyin(flp, &fl, sizeof fl);
69443412Snewton				if (error)
69543412Snewton					return error;
69643412Snewton
69743412Snewton				bsd_to_svr4_flock64(&fl, &ifl);
69843412Snewton
69943412Snewton				return copyout(&ifl, SCARG(uap, arg),
70043412Snewton				    sizeof ifl);
70143412Snewton			}
70243412Snewton
70343412Snewton		case SVR4_F_FREESP64:
70443412Snewton			{
70543412Snewton				struct svr4_flock64	 ifl;
70643412Snewton				struct flock		 fl;
70743412Snewton
70843412Snewton				error = copyin(SCARG(uap, arg), &ifl,
70943412Snewton				    sizeof ifl);
71043412Snewton				if (error)
71143412Snewton					return error;
71243412Snewton				svr4_to_bsd_flock64(&ifl, &fl);
71383366Sjulian				return fd_truncate(td, SCARG(uap, fd), &fl);
71443412Snewton			}
71543412Snewton
71643412Snewton		case SVR4_F_REVOKE:
71783366Sjulian			return fd_revoke(td, SCARG(uap, fd));
71843412Snewton
71943412Snewton		default:
72043412Snewton			return ENOSYS;
72143412Snewton		}
72243412Snewton
72343412Snewton	default:
72443412Snewton		return ENOSYS;
72543412Snewton	}
72643412Snewton}
727