svr4_fcntl.c revision 150663
1139743Simp/*-
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.
3043412Snewton */
31101709Srwatson
32116174Sobrien#include <sys/cdefs.h>
33116174Sobrien__FBSDID("$FreeBSD: head/sys/compat/svr4/svr4_fcntl.c 150663 2005-09-28 07:03:03Z rwatson $");
34116174Sobrien
35101709Srwatson#include "opt_mac.h"
36101709Srwatson
3743412Snewton#include <sys/param.h>
3843412Snewton#include <sys/systm.h>
3943412Snewton#include <sys/file.h>
4043412Snewton#include <sys/filedesc.h>
4143412Snewton/*#include <sys/ioctl.h>*/
4276166Smarkm#include <sys/lock.h>
43101709Srwatson#include <sys/mac.h>
44141486Sjhb#include <sys/malloc.h>
4543412Snewton#include <sys/mount.h>
4676166Smarkm#include <sys/mutex.h>
4776166Smarkm#include <sys/namei.h>
4876166Smarkm#include <sys/proc.h>
4976166Smarkm#include <sys/stat.h>
50134266Sjhb#include <sys/syscallsubr.h>
5176166Smarkm#include <sys/unistd.h>
5243412Snewton#include <sys/vnode.h>
5343412Snewton
5443412Snewton#include <sys/sysproto.h>
5543412Snewton
5665302Sobrien#include <compat/svr4/svr4.h>
5765302Sobrien#include <compat/svr4/svr4_types.h>
5865302Sobrien#include <compat/svr4/svr4_signal.h>
5965302Sobrien#include <compat/svr4/svr4_proto.h>
6065302Sobrien#include <compat/svr4/svr4_util.h>
6165302Sobrien#include <compat/svr4/svr4_fcntl.h>
6243412Snewton
6392761Salfredstatic int svr4_to_bsd_flags(int);
6492761Salfredstatic u_long svr4_to_bsd_cmd(u_long);
6592761Salfredstatic int fd_revoke(struct thread *, int);
6692761Salfredstatic int fd_truncate(struct thread *, int, struct flock *);
6792761Salfredstatic int bsd_to_svr4_flags(int);
6892761Salfredstatic void bsd_to_svr4_flock(struct flock *, struct svr4_flock *);
6992761Salfredstatic void svr4_to_bsd_flock(struct svr4_flock *, struct flock *);
7092761Salfredstatic void bsd_to_svr4_flock64(struct flock *, struct svr4_flock64 *);
7192761Salfredstatic void svr4_to_bsd_flock64(struct svr4_flock64 *, struct flock *);
7243412Snewton
7343412Snewtonstatic u_long
7443412Snewtonsvr4_to_bsd_cmd(cmd)
7543412Snewton	u_long	cmd;
7643412Snewton{
7743412Snewton	switch (cmd) {
7843412Snewton	case SVR4_F_DUPFD:
7943412Snewton		return F_DUPFD;
8043412Snewton	case SVR4_F_GETFD:
8143412Snewton		return F_GETFD;
8243412Snewton	case SVR4_F_SETFD:
8343412Snewton		return F_SETFD;
8443412Snewton	case SVR4_F_GETFL:
8543412Snewton		return F_GETFL;
8643412Snewton	case SVR4_F_SETFL:
8743412Snewton		return F_SETFL;
8843412Snewton	case SVR4_F_GETLK:
8943412Snewton		return F_GETLK;
9043412Snewton	case SVR4_F_SETLK:
9143412Snewton		return F_SETLK;
9243412Snewton	case SVR4_F_SETLKW:
9343412Snewton		return F_SETLKW;
9443412Snewton	default:
9543412Snewton		return -1;
9643412Snewton	}
9743412Snewton}
9843412Snewton
9943412Snewtonstatic int
10043412Snewtonsvr4_to_bsd_flags(l)
10143412Snewton	int	l;
10243412Snewton{
10343412Snewton	int	r = 0;
10443412Snewton	r |= (l & SVR4_O_RDONLY) ? O_RDONLY : 0;
10543412Snewton	r |= (l & SVR4_O_WRONLY) ? O_WRONLY : 0;
10643412Snewton	r |= (l & SVR4_O_RDWR) ? O_RDWR : 0;
10743412Snewton	r |= (l & SVR4_O_NDELAY) ? O_NONBLOCK : 0;
10843412Snewton	r |= (l & SVR4_O_APPEND) ? O_APPEND : 0;
10943412Snewton	r |= (l & SVR4_O_SYNC) ? O_FSYNC : 0;
11043412Snewton	r |= (l & SVR4_O_NONBLOCK) ? O_NONBLOCK : 0;
11143412Snewton	r |= (l & SVR4_O_PRIV) ? O_EXLOCK : 0;
11243412Snewton	r |= (l & SVR4_O_CREAT) ? O_CREAT : 0;
11343412Snewton	r |= (l & SVR4_O_TRUNC) ? O_TRUNC : 0;
11443412Snewton	r |= (l & SVR4_O_EXCL) ? O_EXCL : 0;
11543412Snewton	r |= (l & SVR4_O_NOCTTY) ? O_NOCTTY : 0;
11643412Snewton	return r;
11743412Snewton}
11843412Snewton
11943412Snewtonstatic int
12043412Snewtonbsd_to_svr4_flags(l)
12143412Snewton	int	l;
12243412Snewton{
12343412Snewton	int	r = 0;
12443412Snewton	r |= (l & O_RDONLY) ? SVR4_O_RDONLY : 0;
12543412Snewton	r |= (l & O_WRONLY) ? SVR4_O_WRONLY : 0;
12643412Snewton	r |= (l & O_RDWR) ? SVR4_O_RDWR : 0;
12743412Snewton	r |= (l & O_NDELAY) ? SVR4_O_NONBLOCK : 0;
12843412Snewton	r |= (l & O_APPEND) ? SVR4_O_APPEND : 0;
12943412Snewton	r |= (l & O_FSYNC) ? SVR4_O_SYNC : 0;
13043412Snewton	r |= (l & O_NONBLOCK) ? SVR4_O_NONBLOCK : 0;
13143412Snewton	r |= (l & O_EXLOCK) ? SVR4_O_PRIV : 0;
13243412Snewton	r |= (l & O_CREAT) ? SVR4_O_CREAT : 0;
13343412Snewton	r |= (l & O_TRUNC) ? SVR4_O_TRUNC : 0;
13443412Snewton	r |= (l & O_EXCL) ? SVR4_O_EXCL : 0;
13543412Snewton	r |= (l & O_NOCTTY) ? SVR4_O_NOCTTY : 0;
13643412Snewton	return r;
13743412Snewton}
13843412Snewton
13943412Snewton
14043412Snewtonstatic void
14143412Snewtonbsd_to_svr4_flock(iflp, oflp)
14243412Snewton	struct flock		*iflp;
14343412Snewton	struct svr4_flock	*oflp;
14443412Snewton{
14543412Snewton	switch (iflp->l_type) {
14643412Snewton	case F_RDLCK:
14743412Snewton		oflp->l_type = SVR4_F_RDLCK;
14843412Snewton		break;
14943412Snewton	case F_WRLCK:
15043412Snewton		oflp->l_type = SVR4_F_WRLCK;
15143412Snewton		break;
15243412Snewton	case F_UNLCK:
15343412Snewton		oflp->l_type = SVR4_F_UNLCK;
15443412Snewton		break;
15543412Snewton	default:
15643412Snewton		oflp->l_type = -1;
15743412Snewton		break;
15843412Snewton	}
15943412Snewton
16043412Snewton	oflp->l_whence = (short) iflp->l_whence;
16143412Snewton	oflp->l_start = (svr4_off_t) iflp->l_start;
16243412Snewton	oflp->l_len = (svr4_off_t) iflp->l_len;
16343412Snewton	oflp->l_sysid = 0;
16443412Snewton	oflp->l_pid = (svr4_pid_t) iflp->l_pid;
16543412Snewton}
16643412Snewton
16743412Snewton
16843412Snewtonstatic void
16943412Snewtonsvr4_to_bsd_flock(iflp, oflp)
17043412Snewton	struct svr4_flock	*iflp;
17143412Snewton	struct flock		*oflp;
17243412Snewton{
17343412Snewton	switch (iflp->l_type) {
17443412Snewton	case SVR4_F_RDLCK:
17543412Snewton		oflp->l_type = F_RDLCK;
17643412Snewton		break;
17743412Snewton	case SVR4_F_WRLCK:
17843412Snewton		oflp->l_type = F_WRLCK;
17943412Snewton		break;
18043412Snewton	case SVR4_F_UNLCK:
18143412Snewton		oflp->l_type = F_UNLCK;
18243412Snewton		break;
18343412Snewton	default:
18443412Snewton		oflp->l_type = -1;
18543412Snewton		break;
18643412Snewton	}
18743412Snewton
18843412Snewton	oflp->l_whence = iflp->l_whence;
18943412Snewton	oflp->l_start = (off_t) iflp->l_start;
19043412Snewton	oflp->l_len = (off_t) iflp->l_len;
19143412Snewton	oflp->l_pid = (pid_t) iflp->l_pid;
19243412Snewton
19343412Snewton}
19443412Snewton
19543412Snewtonstatic void
19643412Snewtonbsd_to_svr4_flock64(iflp, oflp)
19743412Snewton	struct flock		*iflp;
19843412Snewton	struct svr4_flock64	*oflp;
19943412Snewton{
20043412Snewton	switch (iflp->l_type) {
20143412Snewton	case F_RDLCK:
20243412Snewton		oflp->l_type = SVR4_F_RDLCK;
20343412Snewton		break;
20443412Snewton	case F_WRLCK:
20543412Snewton		oflp->l_type = SVR4_F_WRLCK;
20643412Snewton		break;
20743412Snewton	case F_UNLCK:
20843412Snewton		oflp->l_type = SVR4_F_UNLCK;
20943412Snewton		break;
21043412Snewton	default:
21143412Snewton		oflp->l_type = -1;
21243412Snewton		break;
21343412Snewton	}
21443412Snewton
21543412Snewton	oflp->l_whence = (short) iflp->l_whence;
21643412Snewton	oflp->l_start = (svr4_off64_t) iflp->l_start;
21743412Snewton	oflp->l_len = (svr4_off64_t) iflp->l_len;
21843412Snewton	oflp->l_sysid = 0;
21943412Snewton	oflp->l_pid = (svr4_pid_t) iflp->l_pid;
22043412Snewton}
22143412Snewton
22243412Snewton
22343412Snewtonstatic void
22443412Snewtonsvr4_to_bsd_flock64(iflp, oflp)
22543412Snewton	struct svr4_flock64	*iflp;
22643412Snewton	struct flock		*oflp;
22743412Snewton{
22843412Snewton	switch (iflp->l_type) {
22943412Snewton	case SVR4_F_RDLCK:
23043412Snewton		oflp->l_type = F_RDLCK;
23143412Snewton		break;
23243412Snewton	case SVR4_F_WRLCK:
23343412Snewton		oflp->l_type = F_WRLCK;
23443412Snewton		break;
23543412Snewton	case SVR4_F_UNLCK:
23643412Snewton		oflp->l_type = F_UNLCK;
23743412Snewton		break;
23843412Snewton	default:
23943412Snewton		oflp->l_type = -1;
24043412Snewton		break;
24143412Snewton	}
24243412Snewton
24343412Snewton	oflp->l_whence = iflp->l_whence;
24443412Snewton	oflp->l_start = (off_t) iflp->l_start;
24543412Snewton	oflp->l_len = (off_t) iflp->l_len;
24643412Snewton	oflp->l_pid = (pid_t) iflp->l_pid;
24743412Snewton
24843412Snewton}
24943412Snewton
25043412Snewton
25143412Snewtonstatic int
25283366Sjulianfd_revoke(td, fd)
25383366Sjulian	struct thread *td;
25443412Snewton	int fd;
25543412Snewton{
25643412Snewton	struct vnode *vp;
25762976Smckusick	struct mount *mp;
25843412Snewton	struct vattr vattr;
25943412Snewton	int error, *retval;
26043412Snewton
26183366Sjulian	retval = td->td_retval;
26289319Salfred	if ((error = fgetvp(td, fd, &vp)) != 0)
26389319Salfred		return (error);
26443412Snewton
26543412Snewton	if (vp->v_type != VCHR && vp->v_type != VBLK) {
26643412Snewton		error = EINVAL;
26743412Snewton		goto out;
26843412Snewton	}
26943412Snewton
270101709Srwatson#ifdef MAC
271101709Srwatson	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
272101709Srwatson	error = mac_check_vnode_revoke(td->td_ucred, vp);
273101709Srwatson	VOP_UNLOCK(vp, 0, td);
274101709Srwatson	if (error)
275101709Srwatson		goto out;
276101709Srwatson#endif
277101709Srwatson
27891406Sjhb	if ((error = VOP_GETATTR(vp, &vattr, td->td_ucred, td)) != 0)
27943412Snewton		goto out;
28043412Snewton
28191406Sjhb	if (td->td_ucred->cr_uid != vattr.va_uid &&
28293593Sjhb	    (error = suser(td)) != 0)
28343412Snewton		goto out;
28443412Snewton
28562976Smckusick	if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
28662976Smckusick		goto out;
28750405Sphk	if (vcount(vp) > 1)
28843412Snewton		VOP_REVOKE(vp, REVOKEALL);
28962976Smckusick	vn_finished_write(mp);
29043412Snewtonout:
29143412Snewton	vrele(vp);
29243412Snewton	return error;
29343412Snewton}
29443412Snewton
29543412Snewton
29643412Snewtonstatic int
29783366Sjulianfd_truncate(td, fd, flp)
29883366Sjulian	struct thread *td;
29943412Snewton	int fd;
30043412Snewton	struct flock *flp;
30143412Snewton{
30243412Snewton	off_t start, length;
30389534Salfred	struct file *fp;
30443412Snewton	struct vnode *vp;
30543412Snewton	struct vattr vattr;
30643412Snewton	int error, *retval;
30743412Snewton	struct ftruncate_args ft;
30843412Snewton
30983366Sjulian	retval = td->td_retval;
31043412Snewton
31143412Snewton	/*
31243412Snewton	 * We only support truncating the file.
31343412Snewton	 */
31489534Salfred	if ((error = fget(td, fd, &fp)) != 0)
31589319Salfred		return (error);
31643412Snewton
317116678Sphk	vp = fp->f_vnode;
31889534Salfred
31989534Salfred	if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) {
32089534Salfred		fdrop(fp, td);
32143412Snewton		return ESPIPE;
32289306Salfred	}
32343412Snewton
32491406Sjhb	if ((error = VOP_GETATTR(vp, &vattr, td->td_ucred, td)) != 0) {
32589534Salfred		fdrop(fp, td);
32643412Snewton		return error;
32789306Salfred	}
32843412Snewton
32943412Snewton	length = vattr.va_size;
33043412Snewton
33143412Snewton	switch (flp->l_whence) {
33243412Snewton	case SEEK_CUR:
33343412Snewton		start = fp->f_offset + flp->l_start;
33443412Snewton		break;
33543412Snewton
33643412Snewton	case SEEK_END:
33743412Snewton		start = flp->l_start + length;
33843412Snewton		break;
33943412Snewton
34043412Snewton	case SEEK_SET:
34143412Snewton		start = flp->l_start;
34243412Snewton		break;
34343412Snewton
34443412Snewton	default:
34589534Salfred		fdrop(fp, td);
34643412Snewton		return EINVAL;
34743412Snewton	}
34843412Snewton
34943412Snewton	if (start + flp->l_len < length) {
35043412Snewton		/* We don't support free'ing in the middle of the file */
35189534Salfred		fdrop(fp, td);
35243412Snewton		return EINVAL;
35343412Snewton	}
35443412Snewton
355107849Salfred	ft.fd = fd;
356107849Salfred	ft.length = start;
35743412Snewton
35889306Salfred	error = ftruncate(td, &ft);
35989306Salfred
36089534Salfred	fdrop(fp, td);
36189306Salfred	return (error);
36243412Snewton}
36343412Snewton
36443412Snewtonint
36583366Sjuliansvr4_sys_open(td, uap)
36683366Sjulian	register struct thread *td;
36743412Snewton	struct svr4_sys_open_args *uap;
36843412Snewton{
36983366Sjulian	struct proc *p = td->td_proc;
370141486Sjhb	char *newpath;
371141486Sjhb	int bsd_flags, error, retval;
37243412Snewton
373141486Sjhb	CHECKALTEXIST(td, uap->path, &newpath);
37443412Snewton
375141486Sjhb	bsd_flags = svr4_to_bsd_flags(uap->flags);
376141486Sjhb	error = kern_open(td, newpath, UIO_SYSSPACE, bsd_flags, uap->mode);
377141486Sjhb	free(newpath, M_TEMP);
37843412Snewton
37943412Snewton	if (error) {
380150663Srwatson	  /*	        uprintf("svr4_open(%s, 0x%0x, 0%o): %d\n", uap->path,
381150663Srwatson			uap->flags, uap->mode, error);*/
38243412Snewton		return error;
38343412Snewton	}
38443412Snewton
38583366Sjulian	retval = td->td_retval[0];
38643412Snewton
38771454Sjhb	PROC_LOCK(p);
388141486Sjhb	if (!(bsd_flags & O_NOCTTY) && SESS_LEADER(p) &&
389141486Sjhb	    !(p->p_flag & P_CONTROLT)) {
39043412Snewton#if defined(NOTYET)
39189306Salfred		struct file	*fp;
39243412Snewton
39389319Salfred		error = fget(td, retval, &fp);
39471454Sjhb		PROC_UNLOCK(p);
39589306Salfred		/*
39689306Salfred		 * we may have lost a race the above open() and
39789306Salfred		 * another thread issuing a close()
39889306Salfred		 */
39989319Salfred		if (error)
40089306Salfred			return (EBADF);	/* XXX: correct errno? */
40143412Snewton		/* ignore any error, just give it a try */
40243412Snewton		if (fp->f_type == DTYPE_VNODE)
403102003Srwatson			fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td->td_ucred,
404102003Srwatson			    td);
40589306Salfred		fdrop(fp, td);
40689306Salfred	} else {
40771454Sjhb		PROC_UNLOCK(p);
40889306Salfred	}
40971454Sjhb#else
41071454Sjhb	}
41171454Sjhb	PROC_UNLOCK(p);
41243412Snewton#endif
41343412Snewton	return error;
41443412Snewton}
41543412Snewton
41643412Snewtonint
41783366Sjuliansvr4_sys_open64(td, uap)
41883366Sjulian	register struct thread *td;
41943412Snewton	struct svr4_sys_open64_args *uap;
42043412Snewton{
42183366Sjulian	return svr4_sys_open(td, (struct svr4_sys_open_args *)uap);
42243412Snewton}
42343412Snewton
42443412Snewtonint
42583366Sjuliansvr4_sys_creat(td, uap)
42683366Sjulian	register struct thread *td;
42743412Snewton	struct svr4_sys_creat_args *uap;
42843412Snewton{
429141486Sjhb	char *newpath;
430141486Sjhb	int error;
43143412Snewton
432141486Sjhb	CHECKALTEXIST(td, uap->path, &newpath);
43343412Snewton
434141486Sjhb	error = kern_open(td, newpath, UIO_SYSSPACE, O_WRONLY | O_CREAT |
435141486Sjhb	    O_TRUNC, uap->mode);
436141486Sjhb	free(newpath, M_TEMP);
437141486Sjhb	return (error);
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
455107849Salfred	ap.fd = uap->fd;
45643412Snewton
45743412Snewton#if BYTE_ORDER == BIG_ENDIAN
458107849Salfred	ap.offset = (((u_int64_t) uap->offset1) << 32) |
459107849Salfred		uap->offset2;
46043412Snewton#else
461107849Salfred	ap.offset = (((u_int64_t) uap->offset2) << 32) |
462107849Salfred		uap->offset1;
46343412Snewton#endif
464107849Salfred	ap.whence = 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{
474141486Sjhb	char *newpath;
475141486Sjhb	int error;
47643412Snewton
477141486Sjhb	CHECKALTEXIST(td, uap->path, &newpath);
478141486Sjhb	error = kern_access(td, newpath, UIO_SYSSPACE, uap->flags);
479141486Sjhb	free(newpath, M_TEMP);
480141486Sjhb	return (error);
48143412Snewton}
48243412Snewton
48343412Snewton#if defined(NOTYET)
48443412Snewtonint
48583366Sjuliansvr4_sys_pread(td, uap)
48683366Sjulian	register struct thread *td;
48743412Snewton	struct svr4_sys_pread_args *uap;
48843412Snewton{
48943412Snewton	struct pread_args pra;
49043412Snewton
49143412Snewton	/*
49243412Snewton	 * Just translate the args structure and call the NetBSD
49343412Snewton	 * pread(2) system call (offset type is 64-bit in NetBSD).
49443412Snewton	 */
495107849Salfred	pra.fd = uap->fd;
496107849Salfred	pra.buf = uap->buf;
497107849Salfred	pra.nbyte = uap->nbyte;
498107849Salfred	pra.offset = uap->off;
49943412Snewton
50083366Sjulian	return pread(td, &pra);
50143412Snewton}
50243412Snewton#endif
50343412Snewton
50443412Snewton#if defined(NOTYET)
50543412Snewtonint
50683366Sjuliansvr4_sys_pread64(td, v, retval)
50783366Sjulian	register struct thread *td;
50843412Snewton	void *v;
50943412Snewton	register_t *retval;
51043412Snewton{
51143412Snewton
51243412Snewton	struct svr4_sys_pread64_args *uap = v;
51343412Snewton	struct sys_pread_args pra;
51443412Snewton
51543412Snewton	/*
51643412Snewton	 * Just translate the args structure and call the NetBSD
51743412Snewton	 * pread(2) system call (offset type is 64-bit in NetBSD).
51843412Snewton	 */
519107849Salfred	pra.fd = uap->fd;
520107849Salfred	pra.buf = uap->buf;
521107849Salfred	pra.nbyte = uap->nbyte;
522107849Salfred	pra.offset = uap->off;
52343412Snewton
52483366Sjulian	return (sys_pread(td, &pra, retval));
52543412Snewton}
52643412Snewton#endif /* NOTYET */
52743412Snewton
52843412Snewton#if defined(NOTYET)
52943412Snewtonint
53083366Sjuliansvr4_sys_pwrite(td, uap)
53183366Sjulian	register struct thread *td;
53243412Snewton	struct svr4_sys_pwrite_args *uap;
53343412Snewton{
53443412Snewton	struct pwrite_args pwa;
53543412Snewton
53643412Snewton	/*
53743412Snewton	 * Just translate the args structure and call the NetBSD
53843412Snewton	 * pwrite(2) system call (offset type is 64-bit in NetBSD).
53943412Snewton	 */
540107849Salfred	pwa.fd = uap->fd;
541107849Salfred	pwa.buf = uap->buf;
542107849Salfred	pwa.nbyte = uap->nbyte;
543107849Salfred	pwa.offset = uap->off;
54443412Snewton
54583366Sjulian	return pwrite(td, &pwa);
54643412Snewton}
54743412Snewton#endif
54843412Snewton
54943412Snewton#if defined(NOTYET)
55043412Snewtonint
55183366Sjuliansvr4_sys_pwrite64(td, v, retval)
55283366Sjulian	register struct thread *td;
55343412Snewton	void *v;
55443412Snewton	register_t *retval;
55543412Snewton{
55643412Snewton	struct svr4_sys_pwrite64_args *uap = v;
55743412Snewton	struct sys_pwrite_args pwa;
55843412Snewton
55943412Snewton	/*
56043412Snewton	 * Just translate the args structure and call the NetBSD
56143412Snewton	 * pwrite(2) system call (offset type is 64-bit in NetBSD).
56243412Snewton	 */
563107849Salfred	pwa.fd = uap->fd;
564107849Salfred	pwa.buf = uap->buf;
565107849Salfred	pwa.nbyte = uap->nbyte;
566107849Salfred	pwa.offset = uap->off;
56743412Snewton
56883366Sjulian	return (sys_pwrite(td, &pwa, retval));
56943412Snewton}
57043412Snewton#endif /* NOTYET */
57143412Snewton
57243412Snewtonint
57383366Sjuliansvr4_sys_fcntl(td, uap)
57483366Sjulian	register struct thread *td;
57543412Snewton	struct svr4_sys_fcntl_args *uap;
57643412Snewton{
577134266Sjhb	int cmd, error, *retval;
57843412Snewton
57983366Sjulian	retval = td->td_retval;
58043412Snewton
581134266Sjhb	cmd = svr4_to_bsd_cmd(uap->cmd);
58243412Snewton
583134266Sjhb	switch (cmd) {
58443412Snewton	case F_DUPFD:
58543412Snewton	case F_GETFD:
58643412Snewton	case F_SETFD:
587134266Sjhb		return (kern_fcntl(td, uap->fd, cmd, (intptr_t)uap->arg));
58843412Snewton
58943412Snewton	case F_GETFL:
590134266Sjhb		error = kern_fcntl(td, uap->fd, cmd, (intptr_t)uap->arg);
59143412Snewton		if (error)
592134266Sjhb			return (error);
59343412Snewton		*retval = bsd_to_svr4_flags(*retval);
594134266Sjhb		return (error);
59543412Snewton
59643412Snewton	case F_SETFL:
59743412Snewton		{
59843412Snewton			/*
59943412Snewton			 * we must save the O_ASYNC flag, as that is
60043412Snewton			 * handled by ioctl(_, I_SETSIG, _) emulation.
60143412Snewton			 */
60243412Snewton			int flags;
60343412Snewton
604107849Salfred			DPRINTF(("Setting flags %p\n", uap->arg));
60543412Snewton
606134266Sjhb			error = kern_fcntl(td, uap->fd, F_GETFL, 0);
607134266Sjhb			if (error)
608134266Sjhb				return (error);
60943412Snewton			flags = *retval;
61043412Snewton			flags &= O_ASYNC;
611107849Salfred			flags |= svr4_to_bsd_flags((u_long) uap->arg);
612134266Sjhb			return (kern_fcntl(td, uap->fd, F_SETFL, flags));
61343412Snewton		}
61443412Snewton
61543412Snewton	case F_GETLK:
61643412Snewton	case F_SETLK:
61743412Snewton	case F_SETLKW:
61843412Snewton		{
619134266Sjhb			struct svr4_flock	ifl;
620134266Sjhb			struct flock		fl;
62143412Snewton
622134266Sjhb			error = copyin(uap->arg, &ifl, sizeof (ifl));
62343412Snewton			if (error)
624134266Sjhb				return (error);
62543412Snewton
62643412Snewton			svr4_to_bsd_flock(&ifl, &fl);
62743412Snewton
628134266Sjhb			error = kern_fcntl(td, uap->fd, cmd, (intptr_t)&fl);
629134266Sjhb			if (error || cmd != F_GETLK)
630134266Sjhb				return (error);
63143412Snewton
63243412Snewton			bsd_to_svr4_flock(&fl, &ifl);
63343412Snewton
634134266Sjhb			return (copyout(&ifl, uap->arg, sizeof (ifl)));
63543412Snewton		}
63643412Snewton	case -1:
637107849Salfred		switch (uap->cmd) {
63843412Snewton		case SVR4_F_DUP2FD:
63943412Snewton			{
64043412Snewton				struct dup2_args du;
64143412Snewton
642107849Salfred				du.from = uap->fd;
643107849Salfred				du.to = (int)uap->arg;
64483366Sjulian				error = dup2(td, &du);
64543412Snewton				if (error)
64643412Snewton					return error;
647107849Salfred				*retval = du.to;
64843412Snewton				return 0;
64943412Snewton			}
65043412Snewton
65143412Snewton		case SVR4_F_FREESP:
65243412Snewton			{
65343412Snewton				struct svr4_flock	 ifl;
65443412Snewton				struct flock		 fl;
65543412Snewton
656107849Salfred				error = copyin(uap->arg, &ifl,
65743412Snewton				    sizeof ifl);
65843412Snewton				if (error)
65943412Snewton					return error;
66043412Snewton				svr4_to_bsd_flock(&ifl, &fl);
661107849Salfred				return fd_truncate(td, uap->fd, &fl);
66243412Snewton			}
66343412Snewton
66443412Snewton		case SVR4_F_GETLK64:
66543412Snewton		case SVR4_F_SETLK64:
66643412Snewton		case SVR4_F_SETLKW64:
66743412Snewton			{
668134266Sjhb				struct svr4_flock64	ifl;
669134266Sjhb				struct flock		fl;
67043412Snewton
671134266Sjhb				switch (uap->cmd) {
672134266Sjhb				case SVR4_F_GETLK64:
673134266Sjhb					cmd = F_GETLK;
674134266Sjhb					break;
675134266Sjhb				case SVR4_F_SETLK64:
676134266Sjhb					cmd = F_SETLK;
677134266Sjhb					break;
678134266Sjhb				case SVR4_F_SETLKW64:
679134266Sjhb					cmd = F_SETLKW;
680134266Sjhb					break;
681134266Sjhb				}
682107849Salfred				error = copyin(uap->arg, &ifl,
683134266Sjhb				    sizeof (ifl));
68443412Snewton				if (error)
685134266Sjhb					return (error);
68643412Snewton
68743412Snewton				svr4_to_bsd_flock64(&ifl, &fl);
68843412Snewton
689134266Sjhb				error = kern_fcntl(td, uap->fd, cmd,
690134266Sjhb				    (intptr_t)&fl);
691134266Sjhb				if (error || cmd != F_GETLK)
692134266Sjhb					return (error);
69343412Snewton
69443412Snewton				bsd_to_svr4_flock64(&fl, &ifl);
69543412Snewton
696134266Sjhb				return (copyout(&ifl, uap->arg,
697134266Sjhb				    sizeof (ifl)));
69843412Snewton			}
69943412Snewton
70043412Snewton		case SVR4_F_FREESP64:
70143412Snewton			{
70243412Snewton				struct svr4_flock64	 ifl;
70343412Snewton				struct flock		 fl;
70443412Snewton
705107849Salfred				error = copyin(uap->arg, &ifl,
70643412Snewton				    sizeof ifl);
70743412Snewton				if (error)
70843412Snewton					return error;
70943412Snewton				svr4_to_bsd_flock64(&ifl, &fl);
710107849Salfred				return fd_truncate(td, uap->fd, &fl);
71143412Snewton			}
71243412Snewton
71343412Snewton		case SVR4_F_REVOKE:
714107849Salfred			return fd_revoke(td, uap->fd);
71543412Snewton
71643412Snewton		default:
71743412Snewton			return ENOSYS;
71843412Snewton		}
71943412Snewton
72043412Snewton	default:
72143412Snewton		return ENOSYS;
72243412Snewton	}
72343412Snewton}
724