svr4_fcntl.c revision 102003
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 102003 2002-08-17 02:36:16Z rwatson $
3243412Snewton */
33101709Srwatson
34101709Srwatson#include "opt_mac.h"
35101709Srwatson
3643412Snewton#include <sys/param.h>
3743412Snewton#include <sys/systm.h>
3843412Snewton#include <sys/file.h>
3943412Snewton#include <sys/filedesc.h>
4043412Snewton/*#include <sys/ioctl.h>*/
4176166Smarkm#include <sys/lock.h>
42101709Srwatson#include <sys/mac.h>
4343412Snewton#include <sys/mount.h>
4476166Smarkm#include <sys/mutex.h>
4576166Smarkm#include <sys/namei.h>
4676166Smarkm#include <sys/proc.h>
4776166Smarkm#include <sys/stat.h>
4876166Smarkm#include <sys/unistd.h>
4943412Snewton#include <sys/vnode.h>
5043412Snewton
5143412Snewton#include <sys/sysproto.h>
5243412Snewton
5365302Sobrien#include <compat/svr4/svr4.h>
5465302Sobrien#include <compat/svr4/svr4_types.h>
5565302Sobrien#include <compat/svr4/svr4_signal.h>
5665302Sobrien#include <compat/svr4/svr4_proto.h>
5765302Sobrien#include <compat/svr4/svr4_util.h>
5865302Sobrien#include <compat/svr4/svr4_fcntl.h>
5943412Snewton
6092761Salfredstatic int svr4_to_bsd_flags(int);
6192761Salfredstatic u_long svr4_to_bsd_cmd(u_long);
6292761Salfredstatic int fd_revoke(struct thread *, int);
6392761Salfredstatic int fd_truncate(struct thread *, int, struct flock *);
6492761Salfredstatic int bsd_to_svr4_flags(int);
6592761Salfredstatic void bsd_to_svr4_flock(struct flock *, struct svr4_flock *);
6692761Salfredstatic void svr4_to_bsd_flock(struct svr4_flock *, struct flock *);
6792761Salfredstatic void bsd_to_svr4_flock64(struct flock *, struct svr4_flock64 *);
6892761Salfredstatic void svr4_to_bsd_flock64(struct svr4_flock64 *, struct flock *);
6943412Snewton
7043412Snewtonstatic u_long
7143412Snewtonsvr4_to_bsd_cmd(cmd)
7243412Snewton	u_long	cmd;
7343412Snewton{
7443412Snewton	switch (cmd) {
7543412Snewton	case SVR4_F_DUPFD:
7643412Snewton		return F_DUPFD;
7743412Snewton	case SVR4_F_GETFD:
7843412Snewton		return F_GETFD;
7943412Snewton	case SVR4_F_SETFD:
8043412Snewton		return F_SETFD;
8143412Snewton	case SVR4_F_GETFL:
8243412Snewton		return F_GETFL;
8343412Snewton	case SVR4_F_SETFL:
8443412Snewton		return F_SETFL;
8543412Snewton	case SVR4_F_GETLK:
8643412Snewton		return F_GETLK;
8743412Snewton	case SVR4_F_SETLK:
8843412Snewton		return F_SETLK;
8943412Snewton	case SVR4_F_SETLKW:
9043412Snewton		return F_SETLKW;
9143412Snewton	default:
9243412Snewton		return -1;
9343412Snewton	}
9443412Snewton}
9543412Snewton
9643412Snewtonstatic int
9743412Snewtonsvr4_to_bsd_flags(l)
9843412Snewton	int	l;
9943412Snewton{
10043412Snewton	int	r = 0;
10143412Snewton	r |= (l & SVR4_O_RDONLY) ? O_RDONLY : 0;
10243412Snewton	r |= (l & SVR4_O_WRONLY) ? O_WRONLY : 0;
10343412Snewton	r |= (l & SVR4_O_RDWR) ? O_RDWR : 0;
10443412Snewton	r |= (l & SVR4_O_NDELAY) ? O_NONBLOCK : 0;
10543412Snewton	r |= (l & SVR4_O_APPEND) ? O_APPEND : 0;
10643412Snewton	r |= (l & SVR4_O_SYNC) ? O_FSYNC : 0;
10743412Snewton	r |= (l & SVR4_O_NONBLOCK) ? O_NONBLOCK : 0;
10843412Snewton	r |= (l & SVR4_O_PRIV) ? O_EXLOCK : 0;
10943412Snewton	r |= (l & SVR4_O_CREAT) ? O_CREAT : 0;
11043412Snewton	r |= (l & SVR4_O_TRUNC) ? O_TRUNC : 0;
11143412Snewton	r |= (l & SVR4_O_EXCL) ? O_EXCL : 0;
11243412Snewton	r |= (l & SVR4_O_NOCTTY) ? O_NOCTTY : 0;
11343412Snewton	return r;
11443412Snewton}
11543412Snewton
11643412Snewtonstatic int
11743412Snewtonbsd_to_svr4_flags(l)
11843412Snewton	int	l;
11943412Snewton{
12043412Snewton	int	r = 0;
12143412Snewton	r |= (l & O_RDONLY) ? SVR4_O_RDONLY : 0;
12243412Snewton	r |= (l & O_WRONLY) ? SVR4_O_WRONLY : 0;
12343412Snewton	r |= (l & O_RDWR) ? SVR4_O_RDWR : 0;
12443412Snewton	r |= (l & O_NDELAY) ? SVR4_O_NONBLOCK : 0;
12543412Snewton	r |= (l & O_APPEND) ? SVR4_O_APPEND : 0;
12643412Snewton	r |= (l & O_FSYNC) ? SVR4_O_SYNC : 0;
12743412Snewton	r |= (l & O_NONBLOCK) ? SVR4_O_NONBLOCK : 0;
12843412Snewton	r |= (l & O_EXLOCK) ? SVR4_O_PRIV : 0;
12943412Snewton	r |= (l & O_CREAT) ? SVR4_O_CREAT : 0;
13043412Snewton	r |= (l & O_TRUNC) ? SVR4_O_TRUNC : 0;
13143412Snewton	r |= (l & O_EXCL) ? SVR4_O_EXCL : 0;
13243412Snewton	r |= (l & O_NOCTTY) ? SVR4_O_NOCTTY : 0;
13343412Snewton	return r;
13443412Snewton}
13543412Snewton
13643412Snewton
13743412Snewtonstatic void
13843412Snewtonbsd_to_svr4_flock(iflp, oflp)
13943412Snewton	struct flock		*iflp;
14043412Snewton	struct svr4_flock	*oflp;
14143412Snewton{
14243412Snewton	switch (iflp->l_type) {
14343412Snewton	case F_RDLCK:
14443412Snewton		oflp->l_type = SVR4_F_RDLCK;
14543412Snewton		break;
14643412Snewton	case F_WRLCK:
14743412Snewton		oflp->l_type = SVR4_F_WRLCK;
14843412Snewton		break;
14943412Snewton	case F_UNLCK:
15043412Snewton		oflp->l_type = SVR4_F_UNLCK;
15143412Snewton		break;
15243412Snewton	default:
15343412Snewton		oflp->l_type = -1;
15443412Snewton		break;
15543412Snewton	}
15643412Snewton
15743412Snewton	oflp->l_whence = (short) iflp->l_whence;
15843412Snewton	oflp->l_start = (svr4_off_t) iflp->l_start;
15943412Snewton	oflp->l_len = (svr4_off_t) iflp->l_len;
16043412Snewton	oflp->l_sysid = 0;
16143412Snewton	oflp->l_pid = (svr4_pid_t) iflp->l_pid;
16243412Snewton}
16343412Snewton
16443412Snewton
16543412Snewtonstatic void
16643412Snewtonsvr4_to_bsd_flock(iflp, oflp)
16743412Snewton	struct svr4_flock	*iflp;
16843412Snewton	struct flock		*oflp;
16943412Snewton{
17043412Snewton	switch (iflp->l_type) {
17143412Snewton	case SVR4_F_RDLCK:
17243412Snewton		oflp->l_type = F_RDLCK;
17343412Snewton		break;
17443412Snewton	case SVR4_F_WRLCK:
17543412Snewton		oflp->l_type = F_WRLCK;
17643412Snewton		break;
17743412Snewton	case SVR4_F_UNLCK:
17843412Snewton		oflp->l_type = F_UNLCK;
17943412Snewton		break;
18043412Snewton	default:
18143412Snewton		oflp->l_type = -1;
18243412Snewton		break;
18343412Snewton	}
18443412Snewton
18543412Snewton	oflp->l_whence = iflp->l_whence;
18643412Snewton	oflp->l_start = (off_t) iflp->l_start;
18743412Snewton	oflp->l_len = (off_t) iflp->l_len;
18843412Snewton	oflp->l_pid = (pid_t) iflp->l_pid;
18943412Snewton
19043412Snewton}
19143412Snewton
19243412Snewtonstatic void
19343412Snewtonbsd_to_svr4_flock64(iflp, oflp)
19443412Snewton	struct flock		*iflp;
19543412Snewton	struct svr4_flock64	*oflp;
19643412Snewton{
19743412Snewton	switch (iflp->l_type) {
19843412Snewton	case F_RDLCK:
19943412Snewton		oflp->l_type = SVR4_F_RDLCK;
20043412Snewton		break;
20143412Snewton	case F_WRLCK:
20243412Snewton		oflp->l_type = SVR4_F_WRLCK;
20343412Snewton		break;
20443412Snewton	case F_UNLCK:
20543412Snewton		oflp->l_type = SVR4_F_UNLCK;
20643412Snewton		break;
20743412Snewton	default:
20843412Snewton		oflp->l_type = -1;
20943412Snewton		break;
21043412Snewton	}
21143412Snewton
21243412Snewton	oflp->l_whence = (short) iflp->l_whence;
21343412Snewton	oflp->l_start = (svr4_off64_t) iflp->l_start;
21443412Snewton	oflp->l_len = (svr4_off64_t) iflp->l_len;
21543412Snewton	oflp->l_sysid = 0;
21643412Snewton	oflp->l_pid = (svr4_pid_t) iflp->l_pid;
21743412Snewton}
21843412Snewton
21943412Snewton
22043412Snewtonstatic void
22143412Snewtonsvr4_to_bsd_flock64(iflp, oflp)
22243412Snewton	struct svr4_flock64	*iflp;
22343412Snewton	struct flock		*oflp;
22443412Snewton{
22543412Snewton	switch (iflp->l_type) {
22643412Snewton	case SVR4_F_RDLCK:
22743412Snewton		oflp->l_type = F_RDLCK;
22843412Snewton		break;
22943412Snewton	case SVR4_F_WRLCK:
23043412Snewton		oflp->l_type = F_WRLCK;
23143412Snewton		break;
23243412Snewton	case SVR4_F_UNLCK:
23343412Snewton		oflp->l_type = F_UNLCK;
23443412Snewton		break;
23543412Snewton	default:
23643412Snewton		oflp->l_type = -1;
23743412Snewton		break;
23843412Snewton	}
23943412Snewton
24043412Snewton	oflp->l_whence = iflp->l_whence;
24143412Snewton	oflp->l_start = (off_t) iflp->l_start;
24243412Snewton	oflp->l_len = (off_t) iflp->l_len;
24343412Snewton	oflp->l_pid = (pid_t) iflp->l_pid;
24443412Snewton
24543412Snewton}
24643412Snewton
24743412Snewton
24843412Snewtonstatic int
24983366Sjulianfd_revoke(td, fd)
25083366Sjulian	struct thread *td;
25143412Snewton	int fd;
25243412Snewton{
25343412Snewton	struct vnode *vp;
25462976Smckusick	struct mount *mp;
25543412Snewton	struct vattr vattr;
25643412Snewton	int error, *retval;
25743412Snewton
25883366Sjulian	retval = td->td_retval;
25989319Salfred	if ((error = fgetvp(td, fd, &vp)) != 0)
26089319Salfred		return (error);
26143412Snewton
26243412Snewton	if (vp->v_type != VCHR && vp->v_type != VBLK) {
26343412Snewton		error = EINVAL;
26443412Snewton		goto out;
26543412Snewton	}
26643412Snewton
267101709Srwatson#ifdef MAC
268101709Srwatson	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
269101709Srwatson	error = mac_check_vnode_revoke(td->td_ucred, vp);
270101709Srwatson	VOP_UNLOCK(vp, 0, td);
271101709Srwatson	if (error)
272101709Srwatson		goto out;
273101709Srwatson#endif
274101709Srwatson
27591406Sjhb	if ((error = VOP_GETATTR(vp, &vattr, td->td_ucred, td)) != 0)
27643412Snewton		goto out;
27743412Snewton
27891406Sjhb	if (td->td_ucred->cr_uid != vattr.va_uid &&
27993593Sjhb	    (error = suser(td)) != 0)
28043412Snewton		goto out;
28143412Snewton
28262976Smckusick	if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
28362976Smckusick		goto out;
28450405Sphk	if (vcount(vp) > 1)
28543412Snewton		VOP_REVOKE(vp, REVOKEALL);
28662976Smckusick	vn_finished_write(mp);
28743412Snewtonout:
28843412Snewton	vrele(vp);
28943412Snewton	return error;
29043412Snewton}
29143412Snewton
29243412Snewton
29343412Snewtonstatic int
29483366Sjulianfd_truncate(td, fd, flp)
29583366Sjulian	struct thread *td;
29643412Snewton	int fd;
29743412Snewton	struct flock *flp;
29843412Snewton{
29943412Snewton	off_t start, length;
30089534Salfred	struct file *fp;
30143412Snewton	struct vnode *vp;
30243412Snewton	struct vattr vattr;
30343412Snewton	int error, *retval;
30443412Snewton	struct ftruncate_args ft;
30543412Snewton
30683366Sjulian	retval = td->td_retval;
30743412Snewton
30843412Snewton	/*
30943412Snewton	 * We only support truncating the file.
31043412Snewton	 */
31189534Salfred	if ((error = fget(td, fd, &fp)) != 0)
31289319Salfred		return (error);
31343412Snewton
31489534Salfred	vp = (struct vnode *) fp->f_data;
31589534Salfred
31689534Salfred	if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) {
31789534Salfred		fdrop(fp, td);
31843412Snewton		return ESPIPE;
31989306Salfred	}
32043412Snewton
32191406Sjhb	if ((error = VOP_GETATTR(vp, &vattr, td->td_ucred, td)) != 0) {
32289534Salfred		fdrop(fp, td);
32343412Snewton		return error;
32489306Salfred	}
32543412Snewton
32643412Snewton	length = vattr.va_size;
32743412Snewton
32843412Snewton	switch (flp->l_whence) {
32943412Snewton	case SEEK_CUR:
33043412Snewton		start = fp->f_offset + flp->l_start;
33143412Snewton		break;
33243412Snewton
33343412Snewton	case SEEK_END:
33443412Snewton		start = flp->l_start + length;
33543412Snewton		break;
33643412Snewton
33743412Snewton	case SEEK_SET:
33843412Snewton		start = flp->l_start;
33943412Snewton		break;
34043412Snewton
34143412Snewton	default:
34289534Salfred		fdrop(fp, td);
34343412Snewton		return EINVAL;
34443412Snewton	}
34543412Snewton
34643412Snewton	if (start + flp->l_len < length) {
34743412Snewton		/* We don't support free'ing in the middle of the file */
34889534Salfred		fdrop(fp, td);
34943412Snewton		return EINVAL;
35043412Snewton	}
35143412Snewton
35243412Snewton	SCARG(&ft, fd) = fd;
35343412Snewton	SCARG(&ft, length) = start;
35443412Snewton
35589306Salfred	error = ftruncate(td, &ft);
35689306Salfred
35789534Salfred	fdrop(fp, td);
35889306Salfred	return (error);
35943412Snewton}
36043412Snewton
36143412Snewtonint
36283366Sjuliansvr4_sys_open(td, uap)
36383366Sjulian	register struct thread *td;
36443412Snewton	struct svr4_sys_open_args *uap;
36543412Snewton{
36683366Sjulian	struct proc *p = td->td_proc;
36743412Snewton	int			error, retval;
36843412Snewton	struct open_args	cup;
36943412Snewton
37043412Snewton	caddr_t sg = stackgap_init();
37183366Sjulian	CHECKALTEXIST(td, &sg, SCARG(uap, path));
37243412Snewton
37343412Snewton	(&cup)->path = uap->path;
37443412Snewton	(&cup)->flags = svr4_to_bsd_flags(uap->flags);
37543412Snewton	(&cup)->mode = uap->mode;
37683366Sjulian	error = open(td, &cup);
37743412Snewton
37843412Snewton	if (error) {
37943412Snewton	  /*	        uprintf("svr4_open(%s, 0x%0x, 0%o): %d\n", uap->path,
38043412Snewton			uap->flags, uap->mode, error);*/
38143412Snewton		return error;
38243412Snewton	}
38343412Snewton
38483366Sjulian	retval = td->td_retval[0];
38543412Snewton
38671454Sjhb	PROC_LOCK(p);
38743412Snewton	if (!(SCARG(&cup, flags) & O_NOCTTY) && SESS_LEADER(p) &&
38883366Sjulian	    !(td->td_proc->p_flag & P_CONTROLT)) {
38943412Snewton#if defined(NOTYET)
39089306Salfred		struct file	*fp;
39143412Snewton
39289319Salfred		error = fget(td, retval, &fp);
39371454Sjhb		PROC_UNLOCK(p);
39489306Salfred		/*
39589306Salfred		 * we may have lost a race the above open() and
39689306Salfred		 * another thread issuing a close()
39789306Salfred		 */
39889319Salfred		if (error)
39989306Salfred			return (EBADF);	/* XXX: correct errno? */
40043412Snewton		/* ignore any error, just give it a try */
40143412Snewton		if (fp->f_type == DTYPE_VNODE)
402102003Srwatson			fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td->td_ucred,
403102003Srwatson			    td);
40489306Salfred		fdrop(fp, td);
40589306Salfred	} else {
40671454Sjhb		PROC_UNLOCK(p);
40789306Salfred	}
40871454Sjhb#else
40971454Sjhb	}
41071454Sjhb	PROC_UNLOCK(p);
41143412Snewton#endif
41243412Snewton	return error;
41343412Snewton}
41443412Snewton
41543412Snewtonint
41683366Sjuliansvr4_sys_open64(td, uap)
41783366Sjulian	register struct thread *td;
41843412Snewton	struct svr4_sys_open64_args *uap;
41943412Snewton{
42083366Sjulian	return svr4_sys_open(td, (struct svr4_sys_open_args *)uap);
42143412Snewton}
42243412Snewton
42343412Snewtonint
42483366Sjuliansvr4_sys_creat(td, uap)
42583366Sjulian	register struct thread *td;
42643412Snewton	struct svr4_sys_creat_args *uap;
42743412Snewton{
42843412Snewton	struct open_args cup;
42943412Snewton
43043412Snewton	caddr_t sg = stackgap_init();
43183366Sjulian	CHECKALTEXIST(td, &sg, SCARG(uap, path));
43243412Snewton
43343412Snewton	SCARG(&cup, path) = SCARG(uap, path);
43443412Snewton	SCARG(&cup, mode) = SCARG(uap, mode);
43543412Snewton	SCARG(&cup, flags) = O_WRONLY | O_CREAT | O_TRUNC;
43643412Snewton
43783366Sjulian	return open(td, &cup);
43843412Snewton}
43943412Snewton
44043412Snewtonint
44183366Sjuliansvr4_sys_creat64(td, uap)
44283366Sjulian	register struct thread *td;
44343412Snewton	struct svr4_sys_creat64_args *uap;
44443412Snewton{
44583366Sjulian	return svr4_sys_creat(td, (struct svr4_sys_creat_args *)uap);
44643412Snewton}
44743412Snewton
44843412Snewtonint
44983366Sjuliansvr4_sys_llseek(td, uap)
45083366Sjulian	register struct thread *td;
45171454Sjhb	struct svr4_sys_llseek_args *uap;
45243412Snewton{
45343412Snewton	struct lseek_args ap;
45443412Snewton
45543412Snewton	SCARG(&ap, fd) = SCARG(uap, fd);
45643412Snewton
45743412Snewton#if BYTE_ORDER == BIG_ENDIAN
45871454Sjhb	SCARG(&ap, offset) = (((u_int64_t) SCARG(uap, offset1)) << 32) |
45943412Snewton		SCARG(uap, offset2);
46043412Snewton#else
46171454Sjhb	SCARG(&ap, offset) = (((u_int64_t) SCARG(uap, offset2)) << 32) |
46243412Snewton		SCARG(uap, offset1);
46343412Snewton#endif
46443412Snewton	SCARG(&ap, whence) = SCARG(uap, whence);
46543412Snewton
46683366Sjulian	return lseek(td, &ap);
46743412Snewton}
46843412Snewton
46943412Snewtonint
47083366Sjuliansvr4_sys_access(td, uap)
47183366Sjulian	register struct thread *td;
47243412Snewton	struct svr4_sys_access_args *uap;
47343412Snewton{
47443412Snewton	struct access_args cup;
47543412Snewton	int *retval;
47643412Snewton
47743412Snewton	caddr_t sg = stackgap_init();
47883366Sjulian	CHECKALTEXIST(td, &sg, SCARG(uap, path));
47943412Snewton
48083366Sjulian	retval = td->td_retval;
48143412Snewton
48243412Snewton	SCARG(&cup, path) = SCARG(uap, path);
48343412Snewton	SCARG(&cup, flags) = SCARG(uap, flags);
48443412Snewton
48583366Sjulian	return access(td, &cup);
48643412Snewton}
48743412Snewton
48843412Snewton#if defined(NOTYET)
48943412Snewtonint
49083366Sjuliansvr4_sys_pread(td, uap)
49183366Sjulian	register struct thread *td;
49243412Snewton	struct svr4_sys_pread_args *uap;
49343412Snewton{
49443412Snewton	struct pread_args pra;
49543412Snewton
49643412Snewton	/*
49743412Snewton	 * Just translate the args structure and call the NetBSD
49843412Snewton	 * pread(2) system call (offset type is 64-bit in NetBSD).
49943412Snewton	 */
50043412Snewton	SCARG(&pra, fd) = SCARG(uap, fd);
50143412Snewton	SCARG(&pra, buf) = SCARG(uap, buf);
50243412Snewton	SCARG(&pra, nbyte) = SCARG(uap, nbyte);
50343412Snewton	SCARG(&pra, offset) = SCARG(uap, off);
50443412Snewton
50583366Sjulian	return pread(td, &pra);
50643412Snewton}
50743412Snewton#endif
50843412Snewton
50943412Snewton#if defined(NOTYET)
51043412Snewtonint
51183366Sjuliansvr4_sys_pread64(td, v, retval)
51283366Sjulian	register struct thread *td;
51343412Snewton	void *v;
51443412Snewton	register_t *retval;
51543412Snewton{
51643412Snewton
51743412Snewton	struct svr4_sys_pread64_args *uap = v;
51843412Snewton	struct sys_pread_args pra;
51943412Snewton
52043412Snewton	/*
52143412Snewton	 * Just translate the args structure and call the NetBSD
52243412Snewton	 * pread(2) system call (offset type is 64-bit in NetBSD).
52343412Snewton	 */
52443412Snewton	SCARG(&pra, fd) = SCARG(uap, fd);
52543412Snewton	SCARG(&pra, buf) = SCARG(uap, buf);
52643412Snewton	SCARG(&pra, nbyte) = SCARG(uap, nbyte);
52743412Snewton	SCARG(&pra, offset) = SCARG(uap, off);
52843412Snewton
52983366Sjulian	return (sys_pread(td, &pra, retval));
53043412Snewton}
53143412Snewton#endif /* NOTYET */
53243412Snewton
53343412Snewton#if defined(NOTYET)
53443412Snewtonint
53583366Sjuliansvr4_sys_pwrite(td, uap)
53683366Sjulian	register struct thread *td;
53743412Snewton	struct svr4_sys_pwrite_args *uap;
53843412Snewton{
53943412Snewton	struct 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 pwrite(td, &pwa);
55143412Snewton}
55243412Snewton#endif
55343412Snewton
55443412Snewton#if defined(NOTYET)
55543412Snewtonint
55683366Sjuliansvr4_sys_pwrite64(td, v, retval)
55783366Sjulian	register struct thread *td;
55843412Snewton	void *v;
55943412Snewton	register_t *retval;
56043412Snewton{
56143412Snewton	struct svr4_sys_pwrite64_args *uap = v;
56243412Snewton	struct sys_pwrite_args pwa;
56343412Snewton
56443412Snewton	/*
56543412Snewton	 * Just translate the args structure and call the NetBSD
56643412Snewton	 * pwrite(2) system call (offset type is 64-bit in NetBSD).
56743412Snewton	 */
56843412Snewton	SCARG(&pwa, fd) = SCARG(uap, fd);
56943412Snewton	SCARG(&pwa, buf) = SCARG(uap, buf);
57043412Snewton	SCARG(&pwa, nbyte) = SCARG(uap, nbyte);
57143412Snewton	SCARG(&pwa, offset) = SCARG(uap, off);
57243412Snewton
57383366Sjulian	return (sys_pwrite(td, &pwa, retval));
57443412Snewton}
57543412Snewton#endif /* NOTYET */
57643412Snewton
57743412Snewtonint
57883366Sjuliansvr4_sys_fcntl(td, uap)
57983366Sjulian	register struct thread *td;
58043412Snewton	struct svr4_sys_fcntl_args *uap;
58143412Snewton{
58243412Snewton	int				error;
58343412Snewton	struct fcntl_args		fa;
58443412Snewton	int                             *retval;
58543412Snewton
58683366Sjulian	retval = td->td_retval;
58743412Snewton
58843412Snewton	SCARG(&fa, fd) = SCARG(uap, fd);
58943412Snewton	SCARG(&fa, cmd) = svr4_to_bsd_cmd(SCARG(uap, cmd));
59043412Snewton
59143412Snewton	switch (SCARG(&fa, cmd)) {
59243412Snewton	case F_DUPFD:
59343412Snewton	case F_GETFD:
59443412Snewton	case F_SETFD:
59543412Snewton		SCARG(&fa, arg) = (long) SCARG(uap, arg);
59683366Sjulian		return fcntl(td, &fa);
59743412Snewton
59843412Snewton	case F_GETFL:
59943412Snewton		SCARG(&fa, arg) = (long) SCARG(uap, arg);
60083366Sjulian		error = fcntl(td, &fa);
60143412Snewton		if (error)
60243412Snewton			return error;
60343412Snewton		*retval = bsd_to_svr4_flags(*retval);
60443412Snewton		return error;
60543412Snewton
60643412Snewton	case F_SETFL:
60743412Snewton		{
60843412Snewton			/*
60943412Snewton			 * we must save the O_ASYNC flag, as that is
61043412Snewton			 * handled by ioctl(_, I_SETSIG, _) emulation.
61143412Snewton			 */
61243412Snewton			long cmd;
61343412Snewton			int flags;
61443412Snewton
61580114Sassar			DPRINTF(("Setting flags %p\n", SCARG(uap, arg)));
61643412Snewton			cmd = SCARG(&fa, cmd); /* save it for a while */
61743412Snewton
61843412Snewton			SCARG(&fa, cmd) = F_GETFL;
61983366Sjulian			if ((error = fcntl(td, &fa)) != 0)
62043412Snewton				return error;
62143412Snewton			flags = *retval;
62243412Snewton			flags &= O_ASYNC;
62343412Snewton			flags |= svr4_to_bsd_flags((u_long) SCARG(uap, arg));
62443412Snewton			SCARG(&fa, cmd) = cmd;
62543412Snewton			SCARG(&fa, arg) = (long) flags;
62683366Sjulian			return fcntl(td, &fa);
62743412Snewton		}
62843412Snewton
62943412Snewton	case F_GETLK:
63043412Snewton	case F_SETLK:
63143412Snewton	case F_SETLKW:
63243412Snewton		{
63343412Snewton			struct svr4_flock	 ifl;
63443412Snewton			struct flock		*flp, fl;
63543412Snewton			caddr_t sg = stackgap_init();
63643412Snewton
63743412Snewton			flp = stackgap_alloc(&sg, sizeof(struct flock));
63843412Snewton			SCARG(&fa, arg) = (long) flp;
63943412Snewton
64043412Snewton			error = copyin(SCARG(uap, arg), &ifl, sizeof ifl);
64143412Snewton			if (error)
64243412Snewton				return error;
64343412Snewton
64443412Snewton			svr4_to_bsd_flock(&ifl, &fl);
64543412Snewton
64643412Snewton			error = copyout(&fl, flp, sizeof fl);
64743412Snewton			if (error)
64843412Snewton				return error;
64943412Snewton
65083366Sjulian			error = fcntl(td, &fa);
65143412Snewton			if (error || SCARG(&fa, cmd) != F_GETLK)
65243412Snewton				return error;
65343412Snewton
65443412Snewton			error = copyin(flp, &fl, sizeof fl);
65543412Snewton			if (error)
65643412Snewton				return error;
65743412Snewton
65843412Snewton			bsd_to_svr4_flock(&fl, &ifl);
65943412Snewton
66043412Snewton			return copyout(&ifl, SCARG(uap, arg), sizeof ifl);
66143412Snewton		}
66243412Snewton	case -1:
66343412Snewton		switch (SCARG(uap, cmd)) {
66443412Snewton		case SVR4_F_DUP2FD:
66543412Snewton			{
66643412Snewton				struct dup2_args du;
66743412Snewton
66843412Snewton				SCARG(&du, from) = SCARG(uap, fd);
66943412Snewton				SCARG(&du, to) = (int)SCARG(uap, arg);
67083366Sjulian				error = dup2(td, &du);
67143412Snewton				if (error)
67243412Snewton					return error;
67343412Snewton				*retval = SCARG(&du, to);
67443412Snewton				return 0;
67543412Snewton			}
67643412Snewton
67743412Snewton		case SVR4_F_FREESP:
67843412Snewton			{
67943412Snewton				struct svr4_flock	 ifl;
68043412Snewton				struct flock		 fl;
68143412Snewton
68243412Snewton				error = copyin(SCARG(uap, arg), &ifl,
68343412Snewton				    sizeof ifl);
68443412Snewton				if (error)
68543412Snewton					return error;
68643412Snewton				svr4_to_bsd_flock(&ifl, &fl);
68783366Sjulian				return fd_truncate(td, SCARG(uap, fd), &fl);
68843412Snewton			}
68943412Snewton
69043412Snewton		case SVR4_F_GETLK64:
69143412Snewton		case SVR4_F_SETLK64:
69243412Snewton		case SVR4_F_SETLKW64:
69343412Snewton			{
69443412Snewton				struct svr4_flock64	 ifl;
69543412Snewton				struct flock		*flp, fl;
69643412Snewton				caddr_t sg = stackgap_init();
69743412Snewton
69843412Snewton				flp = stackgap_alloc(&sg, sizeof(struct flock));
69943412Snewton				SCARG(&fa, arg) = (long) flp;
70043412Snewton
70143412Snewton				error = copyin(SCARG(uap, arg), &ifl,
70243412Snewton				    sizeof ifl);
70343412Snewton				if (error)
70443412Snewton					return error;
70543412Snewton
70643412Snewton				svr4_to_bsd_flock64(&ifl, &fl);
70743412Snewton
70843412Snewton				error = copyout(&fl, flp, sizeof fl);
70943412Snewton				if (error)
71043412Snewton					return error;
71143412Snewton
71283366Sjulian				error = fcntl(td, &fa);
71343412Snewton				if (error || SCARG(&fa, cmd) != F_GETLK)
71443412Snewton					return error;
71543412Snewton
71643412Snewton				error = copyin(flp, &fl, sizeof fl);
71743412Snewton				if (error)
71843412Snewton					return error;
71943412Snewton
72043412Snewton				bsd_to_svr4_flock64(&fl, &ifl);
72143412Snewton
72243412Snewton				return copyout(&ifl, SCARG(uap, arg),
72343412Snewton				    sizeof ifl);
72443412Snewton			}
72543412Snewton
72643412Snewton		case SVR4_F_FREESP64:
72743412Snewton			{
72843412Snewton				struct svr4_flock64	 ifl;
72943412Snewton				struct flock		 fl;
73043412Snewton
73143412Snewton				error = copyin(SCARG(uap, arg), &ifl,
73243412Snewton				    sizeof ifl);
73343412Snewton				if (error)
73443412Snewton					return error;
73543412Snewton				svr4_to_bsd_flock64(&ifl, &fl);
73683366Sjulian				return fd_truncate(td, SCARG(uap, fd), &fl);
73743412Snewton			}
73843412Snewton
73943412Snewton		case SVR4_F_REVOKE:
74083366Sjulian			return fd_revoke(td, SCARG(uap, fd));
74143412Snewton
74243412Snewton		default:
74343412Snewton			return ENOSYS;
74443412Snewton		}
74543412Snewton
74643412Snewton	default:
74743412Snewton		return ENOSYS;
74843412Snewton	}
74943412Snewton}
750