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: releng/11.0/sys/compat/svr4/svr4_fcntl.c 274476 2014-11-13 18:01:51Z kib $");
34116174Sobrien
3543412Snewton#include <sys/param.h>
36263233Srwatson#include <sys/capsicum.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>
42141486Sjhb#include <sys/malloc.h>
4343412Snewton#include <sys/mount.h>
4476166Smarkm#include <sys/mutex.h>
4576166Smarkm#include <sys/namei.h>
46164033Srwatson#include <sys/priv.h>
4776166Smarkm#include <sys/proc.h>
4876166Smarkm#include <sys/stat.h>
49134266Sjhb#include <sys/syscallsubr.h>
5076166Smarkm#include <sys/unistd.h>
5143412Snewton#include <sys/vnode.h>
5243412Snewton
5343412Snewton#include <sys/sysproto.h>
5443412Snewton
5565302Sobrien#include <compat/svr4/svr4.h>
5665302Sobrien#include <compat/svr4/svr4_types.h>
5765302Sobrien#include <compat/svr4/svr4_signal.h>
5865302Sobrien#include <compat/svr4/svr4_proto.h>
5965302Sobrien#include <compat/svr4/svr4_util.h>
6065302Sobrien#include <compat/svr4/svr4_fcntl.h>
6143412Snewton
62163606Srwatson#include <security/mac/mac_framework.h>
63163606Srwatson
6492761Salfredstatic int svr4_to_bsd_flags(int);
6592761Salfredstatic u_long svr4_to_bsd_cmd(u_long);
6692761Salfredstatic int fd_revoke(struct thread *, int);
6792761Salfredstatic int fd_truncate(struct thread *, int, struct flock *);
6892761Salfredstatic int bsd_to_svr4_flags(int);
6992761Salfredstatic void bsd_to_svr4_flock(struct flock *, struct svr4_flock *);
7092761Salfredstatic void svr4_to_bsd_flock(struct svr4_flock *, struct flock *);
7192761Salfredstatic void bsd_to_svr4_flock64(struct flock *, struct svr4_flock64 *);
7292761Salfredstatic void svr4_to_bsd_flock64(struct svr4_flock64 *, struct flock *);
7343412Snewton
7443412Snewtonstatic u_long
7543412Snewtonsvr4_to_bsd_cmd(cmd)
7643412Snewton	u_long	cmd;
7743412Snewton{
7843412Snewton	switch (cmd) {
7943412Snewton	case SVR4_F_DUPFD:
8043412Snewton		return F_DUPFD;
81177314Santoine	case SVR4_F_DUP2FD:
82177314Santoine		return F_DUP2FD;
8343412Snewton	case SVR4_F_GETFD:
8443412Snewton		return F_GETFD;
8543412Snewton	case SVR4_F_SETFD:
8643412Snewton		return F_SETFD;
8743412Snewton	case SVR4_F_GETFL:
8843412Snewton		return F_GETFL;
8943412Snewton	case SVR4_F_SETFL:
9043412Snewton		return F_SETFL;
9143412Snewton	case SVR4_F_GETLK:
9243412Snewton		return F_GETLK;
9343412Snewton	case SVR4_F_SETLK:
9443412Snewton		return F_SETLK;
9543412Snewton	case SVR4_F_SETLKW:
9643412Snewton		return F_SETLKW;
9743412Snewton	default:
9843412Snewton		return -1;
9943412Snewton	}
10043412Snewton}
10143412Snewton
10243412Snewtonstatic int
10343412Snewtonsvr4_to_bsd_flags(l)
10443412Snewton	int	l;
10543412Snewton{
10643412Snewton	int	r = 0;
10743412Snewton	r |= (l & SVR4_O_RDONLY) ? O_RDONLY : 0;
10843412Snewton	r |= (l & SVR4_O_WRONLY) ? O_WRONLY : 0;
10943412Snewton	r |= (l & SVR4_O_RDWR) ? O_RDWR : 0;
11043412Snewton	r |= (l & SVR4_O_NDELAY) ? O_NONBLOCK : 0;
11143412Snewton	r |= (l & SVR4_O_APPEND) ? O_APPEND : 0;
11243412Snewton	r |= (l & SVR4_O_SYNC) ? O_FSYNC : 0;
11343412Snewton	r |= (l & SVR4_O_NONBLOCK) ? O_NONBLOCK : 0;
11443412Snewton	r |= (l & SVR4_O_PRIV) ? O_EXLOCK : 0;
11543412Snewton	r |= (l & SVR4_O_CREAT) ? O_CREAT : 0;
11643412Snewton	r |= (l & SVR4_O_TRUNC) ? O_TRUNC : 0;
11743412Snewton	r |= (l & SVR4_O_EXCL) ? O_EXCL : 0;
11843412Snewton	r |= (l & SVR4_O_NOCTTY) ? O_NOCTTY : 0;
11943412Snewton	return r;
12043412Snewton}
12143412Snewton
12243412Snewtonstatic int
12343412Snewtonbsd_to_svr4_flags(l)
12443412Snewton	int	l;
12543412Snewton{
12643412Snewton	int	r = 0;
12743412Snewton	r |= (l & O_RDONLY) ? SVR4_O_RDONLY : 0;
12843412Snewton	r |= (l & O_WRONLY) ? SVR4_O_WRONLY : 0;
12943412Snewton	r |= (l & O_RDWR) ? SVR4_O_RDWR : 0;
13043412Snewton	r |= (l & O_NDELAY) ? SVR4_O_NONBLOCK : 0;
13143412Snewton	r |= (l & O_APPEND) ? SVR4_O_APPEND : 0;
13243412Snewton	r |= (l & O_FSYNC) ? SVR4_O_SYNC : 0;
13343412Snewton	r |= (l & O_NONBLOCK) ? SVR4_O_NONBLOCK : 0;
13443412Snewton	r |= (l & O_EXLOCK) ? SVR4_O_PRIV : 0;
13543412Snewton	r |= (l & O_CREAT) ? SVR4_O_CREAT : 0;
13643412Snewton	r |= (l & O_TRUNC) ? SVR4_O_TRUNC : 0;
13743412Snewton	r |= (l & O_EXCL) ? SVR4_O_EXCL : 0;
13843412Snewton	r |= (l & O_NOCTTY) ? SVR4_O_NOCTTY : 0;
13943412Snewton	return r;
14043412Snewton}
14143412Snewton
14243412Snewton
14343412Snewtonstatic void
14443412Snewtonbsd_to_svr4_flock(iflp, oflp)
14543412Snewton	struct flock		*iflp;
14643412Snewton	struct svr4_flock	*oflp;
14743412Snewton{
14843412Snewton	switch (iflp->l_type) {
14943412Snewton	case F_RDLCK:
15043412Snewton		oflp->l_type = SVR4_F_RDLCK;
15143412Snewton		break;
15243412Snewton	case F_WRLCK:
15343412Snewton		oflp->l_type = SVR4_F_WRLCK;
15443412Snewton		break;
15543412Snewton	case F_UNLCK:
15643412Snewton		oflp->l_type = SVR4_F_UNLCK;
15743412Snewton		break;
15843412Snewton	default:
15943412Snewton		oflp->l_type = -1;
16043412Snewton		break;
16143412Snewton	}
16243412Snewton
16343412Snewton	oflp->l_whence = (short) iflp->l_whence;
16443412Snewton	oflp->l_start = (svr4_off_t) iflp->l_start;
16543412Snewton	oflp->l_len = (svr4_off_t) iflp->l_len;
16643412Snewton	oflp->l_sysid = 0;
16743412Snewton	oflp->l_pid = (svr4_pid_t) iflp->l_pid;
16843412Snewton}
16943412Snewton
17043412Snewton
17143412Snewtonstatic void
17243412Snewtonsvr4_to_bsd_flock(iflp, oflp)
17343412Snewton	struct svr4_flock	*iflp;
17443412Snewton	struct flock		*oflp;
17543412Snewton{
17643412Snewton	switch (iflp->l_type) {
17743412Snewton	case SVR4_F_RDLCK:
17843412Snewton		oflp->l_type = F_RDLCK;
17943412Snewton		break;
18043412Snewton	case SVR4_F_WRLCK:
18143412Snewton		oflp->l_type = F_WRLCK;
18243412Snewton		break;
18343412Snewton	case SVR4_F_UNLCK:
18443412Snewton		oflp->l_type = F_UNLCK;
18543412Snewton		break;
18643412Snewton	default:
18743412Snewton		oflp->l_type = -1;
18843412Snewton		break;
18943412Snewton	}
19043412Snewton
19143412Snewton	oflp->l_whence = iflp->l_whence;
19243412Snewton	oflp->l_start = (off_t) iflp->l_start;
19343412Snewton	oflp->l_len = (off_t) iflp->l_len;
19443412Snewton	oflp->l_pid = (pid_t) iflp->l_pid;
195177633Sdfr	oflp->l_sysid = iflp->l_sysid;
19643412Snewton}
19743412Snewton
19843412Snewtonstatic void
19943412Snewtonbsd_to_svr4_flock64(iflp, oflp)
20043412Snewton	struct flock		*iflp;
20143412Snewton	struct svr4_flock64	*oflp;
20243412Snewton{
20343412Snewton	switch (iflp->l_type) {
20443412Snewton	case F_RDLCK:
20543412Snewton		oflp->l_type = SVR4_F_RDLCK;
20643412Snewton		break;
20743412Snewton	case F_WRLCK:
20843412Snewton		oflp->l_type = SVR4_F_WRLCK;
20943412Snewton		break;
21043412Snewton	case F_UNLCK:
21143412Snewton		oflp->l_type = SVR4_F_UNLCK;
21243412Snewton		break;
21343412Snewton	default:
21443412Snewton		oflp->l_type = -1;
21543412Snewton		break;
21643412Snewton	}
21743412Snewton
21843412Snewton	oflp->l_whence = (short) iflp->l_whence;
21943412Snewton	oflp->l_start = (svr4_off64_t) iflp->l_start;
22043412Snewton	oflp->l_len = (svr4_off64_t) iflp->l_len;
221177633Sdfr	oflp->l_sysid = iflp->l_sysid;
22243412Snewton	oflp->l_pid = (svr4_pid_t) iflp->l_pid;
22343412Snewton}
22443412Snewton
22543412Snewton
22643412Snewtonstatic void
22743412Snewtonsvr4_to_bsd_flock64(iflp, oflp)
22843412Snewton	struct svr4_flock64	*iflp;
22943412Snewton	struct flock		*oflp;
23043412Snewton{
23143412Snewton	switch (iflp->l_type) {
23243412Snewton	case SVR4_F_RDLCK:
23343412Snewton		oflp->l_type = F_RDLCK;
23443412Snewton		break;
23543412Snewton	case SVR4_F_WRLCK:
23643412Snewton		oflp->l_type = F_WRLCK;
23743412Snewton		break;
23843412Snewton	case SVR4_F_UNLCK:
23943412Snewton		oflp->l_type = F_UNLCK;
24043412Snewton		break;
24143412Snewton	default:
24243412Snewton		oflp->l_type = -1;
24343412Snewton		break;
24443412Snewton	}
24543412Snewton
24643412Snewton	oflp->l_whence = iflp->l_whence;
24743412Snewton	oflp->l_start = (off_t) iflp->l_start;
24843412Snewton	oflp->l_len = (off_t) iflp->l_len;
24943412Snewton	oflp->l_pid = (pid_t) iflp->l_pid;
25043412Snewton
25143412Snewton}
25243412Snewton
25343412Snewton
25443412Snewtonstatic int
25583366Sjulianfd_revoke(td, fd)
25683366Sjulian	struct thread *td;
25743412Snewton	int fd;
25843412Snewton{
25943412Snewton	struct vnode *vp;
26062976Smckusick	struct mount *mp;
26143412Snewton	struct vattr vattr;
262255219Spjd	cap_rights_t rights;
26343412Snewton	int error, *retval;
26443412Snewton
26583366Sjulian	retval = td->td_retval;
266224778Srwatson	/*
267224778Srwatson	 * If we ever want to support Capsicum on SVR4 processes (unlikely)
268224778Srwatson	 * or FreeBSD grows a native frevoke() (more likely), we will need a
269247602Spjd	 * CAP_FREVOKE here.
270224778Srwatson	 *
271255219Spjd	 * In the meantime, use CAP_ALL(): if a SVR4 process wants to
272224778Srwatson	 * do an frevoke(), it needs to do it on either a regular file
273224778Srwatson	 * descriptor or a fully-privileged capability (which is effectively
274224778Srwatson	 * the same as a non-capability-restricted file descriptor).
275224778Srwatson	 */
276255219Spjd	CAP_ALL(&rights);
277255219Spjd	if ((error = fgetvp(td, fd, &rights, &vp)) != 0)
27889319Salfred		return (error);
27943412Snewton
28043412Snewton	if (vp->v_type != VCHR && vp->v_type != VBLK) {
28143412Snewton		error = EINVAL;
28243412Snewton		goto out;
28343412Snewton	}
28443412Snewton
285101709Srwatson#ifdef MAC
286175202Sattilio	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
287172930Srwatson	error = mac_vnode_check_revoke(td->td_ucred, vp);
288175294Sattilio	VOP_UNLOCK(vp, 0);
289101709Srwatson	if (error)
290101709Srwatson		goto out;
291101709Srwatson#endif
292101709Srwatson
293182371Sattilio	if ((error = VOP_GETATTR(vp, &vattr, td->td_ucred)) != 0)
29443412Snewton		goto out;
29543412Snewton
29691406Sjhb	if (td->td_ucred->cr_uid != vattr.va_uid &&
297170587Srwatson	    (error = priv_check(td, PRIV_VFS_ADMIN)) != 0)
29843412Snewton		goto out;
29943412Snewton
30062976Smckusick	if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
30162976Smckusick		goto out;
30250405Sphk	if (vcount(vp) > 1)
30343412Snewton		VOP_REVOKE(vp, REVOKEALL);
30462976Smckusick	vn_finished_write(mp);
30543412Snewtonout:
30643412Snewton	vrele(vp);
30743412Snewton	return error;
30843412Snewton}
30943412Snewton
31043412Snewton
31143412Snewtonstatic int
31283366Sjulianfd_truncate(td, fd, flp)
31383366Sjulian	struct thread *td;
31443412Snewton	int fd;
31543412Snewton	struct flock *flp;
31643412Snewton{
31743412Snewton	off_t start, length;
31889534Salfred	struct file *fp;
31943412Snewton	struct vnode *vp;
32043412Snewton	struct vattr vattr;
32143412Snewton	int error, *retval;
32243412Snewton	struct ftruncate_args ft;
323255219Spjd	cap_rights_t rights;
32443412Snewton
32583366Sjulian	retval = td->td_retval;
32643412Snewton
32743412Snewton	/*
32843412Snewton	 * We only support truncating the file.
32943412Snewton	 */
330255219Spjd	error = fget(td, fd, cap_rights_init(&rights, CAP_FTRUNCATE), &fp);
331255219Spjd	if (error != 0)
33289319Salfred		return (error);
33343412Snewton
334116678Sphk	vp = fp->f_vnode;
33589534Salfred
33689534Salfred	if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) {
33789534Salfred		fdrop(fp, td);
33843412Snewton		return ESPIPE;
33989306Salfred	}
34043412Snewton
341182371Sattilio	if ((error = VOP_GETATTR(vp, &vattr, td->td_ucred)) != 0) {
34289534Salfred		fdrop(fp, td);
34343412Snewton		return error;
34489306Salfred	}
34543412Snewton
34643412Snewton	length = vattr.va_size;
34743412Snewton
34843412Snewton	switch (flp->l_whence) {
34943412Snewton	case SEEK_CUR:
35043412Snewton		start = fp->f_offset + flp->l_start;
35143412Snewton		break;
35243412Snewton
35343412Snewton	case SEEK_END:
35443412Snewton		start = flp->l_start + length;
35543412Snewton		break;
35643412Snewton
35743412Snewton	case SEEK_SET:
35843412Snewton		start = flp->l_start;
35943412Snewton		break;
36043412Snewton
36143412Snewton	default:
36289534Salfred		fdrop(fp, td);
36343412Snewton		return EINVAL;
36443412Snewton	}
36543412Snewton
36643412Snewton	if (start + flp->l_len < length) {
36743412Snewton		/* We don't support free'ing in the middle of the file */
36889534Salfred		fdrop(fp, td);
36943412Snewton		return EINVAL;
37043412Snewton	}
37143412Snewton
372107849Salfred	ft.fd = fd;
373107849Salfred	ft.length = start;
37443412Snewton
375225617Skmacy	error = sys_ftruncate(td, &ft);
37689306Salfred
37789534Salfred	fdrop(fp, td);
37889306Salfred	return (error);
37943412Snewton}
38043412Snewton
38143412Snewtonint
38283366Sjuliansvr4_sys_open(td, uap)
383193014Sdelphij	struct thread *td;
38443412Snewton	struct svr4_sys_open_args *uap;
38543412Snewton{
38683366Sjulian	struct proc *p = td->td_proc;
387141486Sjhb	char *newpath;
388141486Sjhb	int bsd_flags, error, retval;
38943412Snewton
390141486Sjhb	CHECKALTEXIST(td, uap->path, &newpath);
39143412Snewton
392141486Sjhb	bsd_flags = svr4_to_bsd_flags(uap->flags);
393274476Skib	error = kern_openat(td, AT_FDCWD, newpath, UIO_SYSSPACE, bsd_flags,
394274476Skib	    uap->mode);
395141486Sjhb	free(newpath, M_TEMP);
39643412Snewton
39743412Snewton	if (error) {
398150663Srwatson	  /*	        uprintf("svr4_open(%s, 0x%0x, 0%o): %d\n", uap->path,
399150663Srwatson			uap->flags, uap->mode, error);*/
40043412Snewton		return error;
40143412Snewton	}
40243412Snewton
40383366Sjulian	retval = td->td_retval[0];
40443412Snewton
40571454Sjhb	PROC_LOCK(p);
406141486Sjhb	if (!(bsd_flags & O_NOCTTY) && SESS_LEADER(p) &&
407141486Sjhb	    !(p->p_flag & P_CONTROLT)) {
40843412Snewton#if defined(NOTYET)
409255219Spjd		cap_rights_t rights;
410255219Spjd		struct file *fp;
41143412Snewton
412255219Spjd		error = fget(td, retval,
413255219Spjd		    cap_rights_init(&rights, CAP_IOCTL), &fp);
41471454Sjhb		PROC_UNLOCK(p);
41589306Salfred		/*
41689306Salfred		 * we may have lost a race the above open() and
41789306Salfred		 * another thread issuing a close()
41889306Salfred		 */
41989319Salfred		if (error)
42089306Salfred			return (EBADF);	/* XXX: correct errno? */
42143412Snewton		/* ignore any error, just give it a try */
42243412Snewton		if (fp->f_type == DTYPE_VNODE)
423102003Srwatson			fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td->td_ucred,
424102003Srwatson			    td);
42589306Salfred		fdrop(fp, td);
42689306Salfred	} else {
42771454Sjhb		PROC_UNLOCK(p);
42889306Salfred	}
42971454Sjhb#else
43071454Sjhb	}
43171454Sjhb	PROC_UNLOCK(p);
43243412Snewton#endif
43343412Snewton	return error;
43443412Snewton}
43543412Snewton
43643412Snewtonint
43783366Sjuliansvr4_sys_open64(td, uap)
438193014Sdelphij	struct thread *td;
43943412Snewton	struct svr4_sys_open64_args *uap;
44043412Snewton{
44183366Sjulian	return svr4_sys_open(td, (struct svr4_sys_open_args *)uap);
44243412Snewton}
44343412Snewton
44443412Snewtonint
44583366Sjuliansvr4_sys_creat(td, uap)
446193014Sdelphij	struct thread *td;
44743412Snewton	struct svr4_sys_creat_args *uap;
44843412Snewton{
449141486Sjhb	char *newpath;
450141486Sjhb	int error;
45143412Snewton
452141486Sjhb	CHECKALTEXIST(td, uap->path, &newpath);
45343412Snewton
454274476Skib	error = kern_openat(td, AT_FDCWD, newpath, UIO_SYSSPACE,
455274476Skib	    O_WRONLY | O_CREAT | O_TRUNC, uap->mode);
456141486Sjhb	free(newpath, M_TEMP);
457141486Sjhb	return (error);
45843412Snewton}
45943412Snewton
46043412Snewtonint
46183366Sjuliansvr4_sys_creat64(td, uap)
462193014Sdelphij	struct thread *td;
46343412Snewton	struct svr4_sys_creat64_args *uap;
46443412Snewton{
46583366Sjulian	return svr4_sys_creat(td, (struct svr4_sys_creat_args *)uap);
46643412Snewton}
46743412Snewton
46843412Snewtonint
46983366Sjuliansvr4_sys_llseek(td, uap)
470193014Sdelphij	struct thread *td;
47171454Sjhb	struct svr4_sys_llseek_args *uap;
47243412Snewton{
47343412Snewton	struct lseek_args ap;
47443412Snewton
475107849Salfred	ap.fd = uap->fd;
47643412Snewton
47743412Snewton#if BYTE_ORDER == BIG_ENDIAN
478107849Salfred	ap.offset = (((u_int64_t) uap->offset1) << 32) |
479107849Salfred		uap->offset2;
48043412Snewton#else
481107849Salfred	ap.offset = (((u_int64_t) uap->offset2) << 32) |
482107849Salfred		uap->offset1;
48343412Snewton#endif
484107849Salfred	ap.whence = uap->whence;
48543412Snewton
486225617Skmacy	return sys_lseek(td, &ap);
48743412Snewton}
48843412Snewton
48943412Snewtonint
49083366Sjuliansvr4_sys_access(td, uap)
491193014Sdelphij	struct thread *td;
49243412Snewton	struct svr4_sys_access_args *uap;
49343412Snewton{
494141486Sjhb	char *newpath;
495141486Sjhb	int error;
49643412Snewton
497141486Sjhb	CHECKALTEXIST(td, uap->path, &newpath);
498274476Skib	error = kern_accessat(td, AT_FDCWD, newpath, UIO_SYSSPACE,
499274476Skib	    0, uap->amode);
500141486Sjhb	free(newpath, M_TEMP);
501141486Sjhb	return (error);
50243412Snewton}
50343412Snewton
50443412Snewton#if defined(NOTYET)
50543412Snewtonint
50683366Sjuliansvr4_sys_pread(td, uap)
507193014Sdelphij	struct thread *td;
50843412Snewton	struct svr4_sys_pread_args *uap;
50943412Snewton{
51043412Snewton	struct pread_args pra;
51143412Snewton
51243412Snewton	/*
51343412Snewton	 * Just translate the args structure and call the NetBSD
51443412Snewton	 * pread(2) system call (offset type is 64-bit in NetBSD).
51543412Snewton	 */
516107849Salfred	pra.fd = uap->fd;
517107849Salfred	pra.buf = uap->buf;
518107849Salfred	pra.nbyte = uap->nbyte;
519107849Salfred	pra.offset = uap->off;
52043412Snewton
52183366Sjulian	return pread(td, &pra);
52243412Snewton}
52343412Snewton#endif
52443412Snewton
52543412Snewton#if defined(NOTYET)
52643412Snewtonint
52783366Sjuliansvr4_sys_pread64(td, v, retval)
528193014Sdelphij	struct thread *td;
52943412Snewton	void *v;
53043412Snewton	register_t *retval;
53143412Snewton{
53243412Snewton
53343412Snewton	struct svr4_sys_pread64_args *uap = v;
53443412Snewton	struct sys_pread_args pra;
53543412Snewton
53643412Snewton	/*
53743412Snewton	 * Just translate the args structure and call the NetBSD
53843412Snewton	 * pread(2) system call (offset type is 64-bit in NetBSD).
53943412Snewton	 */
540107849Salfred	pra.fd = uap->fd;
541107849Salfred	pra.buf = uap->buf;
542107849Salfred	pra.nbyte = uap->nbyte;
543107849Salfred	pra.offset = uap->off;
54443412Snewton
54583366Sjulian	return (sys_pread(td, &pra, retval));
54643412Snewton}
54743412Snewton#endif /* NOTYET */
54843412Snewton
54943412Snewton#if defined(NOTYET)
55043412Snewtonint
55183366Sjuliansvr4_sys_pwrite(td, uap)
552193014Sdelphij	struct thread *td;
55343412Snewton	struct svr4_sys_pwrite_args *uap;
55443412Snewton{
55543412Snewton	struct pwrite_args pwa;
55643412Snewton
55743412Snewton	/*
55843412Snewton	 * Just translate the args structure and call the NetBSD
55943412Snewton	 * pwrite(2) system call (offset type is 64-bit in NetBSD).
56043412Snewton	 */
561107849Salfred	pwa.fd = uap->fd;
562107849Salfred	pwa.buf = uap->buf;
563107849Salfred	pwa.nbyte = uap->nbyte;
564107849Salfred	pwa.offset = uap->off;
56543412Snewton
56683366Sjulian	return pwrite(td, &pwa);
56743412Snewton}
56843412Snewton#endif
56943412Snewton
57043412Snewton#if defined(NOTYET)
57143412Snewtonint
57283366Sjuliansvr4_sys_pwrite64(td, v, retval)
573193014Sdelphij	struct thread *td;
57443412Snewton	void *v;
57543412Snewton	register_t *retval;
57643412Snewton{
57743412Snewton	struct svr4_sys_pwrite64_args *uap = v;
57843412Snewton	struct sys_pwrite_args pwa;
57943412Snewton
58043412Snewton	/*
58143412Snewton	 * Just translate the args structure and call the NetBSD
58243412Snewton	 * pwrite(2) system call (offset type is 64-bit in NetBSD).
58343412Snewton	 */
584107849Salfred	pwa.fd = uap->fd;
585107849Salfred	pwa.buf = uap->buf;
586107849Salfred	pwa.nbyte = uap->nbyte;
587107849Salfred	pwa.offset = uap->off;
58843412Snewton
58983366Sjulian	return (sys_pwrite(td, &pwa, retval));
59043412Snewton}
59143412Snewton#endif /* NOTYET */
59243412Snewton
59343412Snewtonint
59483366Sjuliansvr4_sys_fcntl(td, uap)
595193014Sdelphij	struct thread *td;
59643412Snewton	struct svr4_sys_fcntl_args *uap;
59743412Snewton{
598134266Sjhb	int cmd, error, *retval;
59943412Snewton
60083366Sjulian	retval = td->td_retval;
60143412Snewton
602134266Sjhb	cmd = svr4_to_bsd_cmd(uap->cmd);
60343412Snewton
604134266Sjhb	switch (cmd) {
60543412Snewton	case F_DUPFD:
606177314Santoine	case F_DUP2FD:
60743412Snewton	case F_GETFD:
60843412Snewton	case F_SETFD:
609134266Sjhb		return (kern_fcntl(td, uap->fd, cmd, (intptr_t)uap->arg));
61043412Snewton
61143412Snewton	case F_GETFL:
612134266Sjhb		error = kern_fcntl(td, uap->fd, cmd, (intptr_t)uap->arg);
61343412Snewton		if (error)
614134266Sjhb			return (error);
61543412Snewton		*retval = bsd_to_svr4_flags(*retval);
616134266Sjhb		return (error);
61743412Snewton
61843412Snewton	case F_SETFL:
61943412Snewton		{
62043412Snewton			/*
62143412Snewton			 * we must save the O_ASYNC flag, as that is
62243412Snewton			 * handled by ioctl(_, I_SETSIG, _) emulation.
62343412Snewton			 */
62443412Snewton			int flags;
62543412Snewton
626107849Salfred			DPRINTF(("Setting flags %p\n", uap->arg));
62743412Snewton
628134266Sjhb			error = kern_fcntl(td, uap->fd, F_GETFL, 0);
629134266Sjhb			if (error)
630134266Sjhb				return (error);
63143412Snewton			flags = *retval;
63243412Snewton			flags &= O_ASYNC;
633107849Salfred			flags |= svr4_to_bsd_flags((u_long) uap->arg);
634134266Sjhb			return (kern_fcntl(td, uap->fd, F_SETFL, flags));
63543412Snewton		}
63643412Snewton
63743412Snewton	case F_GETLK:
63843412Snewton	case F_SETLK:
63943412Snewton	case F_SETLKW:
64043412Snewton		{
641134266Sjhb			struct svr4_flock	ifl;
642134266Sjhb			struct flock		fl;
64343412Snewton
644134266Sjhb			error = copyin(uap->arg, &ifl, sizeof (ifl));
64543412Snewton			if (error)
646134266Sjhb				return (error);
64743412Snewton
64843412Snewton			svr4_to_bsd_flock(&ifl, &fl);
64943412Snewton
650134266Sjhb			error = kern_fcntl(td, uap->fd, cmd, (intptr_t)&fl);
651134266Sjhb			if (error || cmd != F_GETLK)
652134266Sjhb				return (error);
65343412Snewton
65443412Snewton			bsd_to_svr4_flock(&fl, &ifl);
65543412Snewton
656134266Sjhb			return (copyout(&ifl, uap->arg, sizeof (ifl)));
65743412Snewton		}
65843412Snewton	case -1:
659107849Salfred		switch (uap->cmd) {
66043412Snewton		case SVR4_F_FREESP:
66143412Snewton			{
66243412Snewton				struct svr4_flock	 ifl;
66343412Snewton				struct flock		 fl;
66443412Snewton
665107849Salfred				error = copyin(uap->arg, &ifl,
66643412Snewton				    sizeof ifl);
66743412Snewton				if (error)
66843412Snewton					return error;
66943412Snewton				svr4_to_bsd_flock(&ifl, &fl);
670107849Salfred				return fd_truncate(td, uap->fd, &fl);
67143412Snewton			}
67243412Snewton
67343412Snewton		case SVR4_F_GETLK64:
67443412Snewton		case SVR4_F_SETLK64:
67543412Snewton		case SVR4_F_SETLKW64:
67643412Snewton			{
677134266Sjhb				struct svr4_flock64	ifl;
678134266Sjhb				struct flock		fl;
67943412Snewton
680134266Sjhb				switch (uap->cmd) {
681134266Sjhb				case SVR4_F_GETLK64:
682134266Sjhb					cmd = F_GETLK;
683134266Sjhb					break;
684134266Sjhb				case SVR4_F_SETLK64:
685134266Sjhb					cmd = F_SETLK;
686134266Sjhb					break;
687134266Sjhb				case SVR4_F_SETLKW64:
688134266Sjhb					cmd = F_SETLKW;
689134266Sjhb					break;
690134266Sjhb				}
691107849Salfred				error = copyin(uap->arg, &ifl,
692134266Sjhb				    sizeof (ifl));
69343412Snewton				if (error)
694134266Sjhb					return (error);
69543412Snewton
69643412Snewton				svr4_to_bsd_flock64(&ifl, &fl);
69743412Snewton
698134266Sjhb				error = kern_fcntl(td, uap->fd, cmd,
699134266Sjhb				    (intptr_t)&fl);
700134266Sjhb				if (error || cmd != F_GETLK)
701134266Sjhb					return (error);
70243412Snewton
70343412Snewton				bsd_to_svr4_flock64(&fl, &ifl);
70443412Snewton
705134266Sjhb				return (copyout(&ifl, uap->arg,
706134266Sjhb				    sizeof (ifl)));
70743412Snewton			}
70843412Snewton
70943412Snewton		case SVR4_F_FREESP64:
71043412Snewton			{
71143412Snewton				struct svr4_flock64	 ifl;
71243412Snewton				struct flock		 fl;
71343412Snewton
714107849Salfred				error = copyin(uap->arg, &ifl,
71543412Snewton				    sizeof ifl);
71643412Snewton				if (error)
71743412Snewton					return error;
71843412Snewton				svr4_to_bsd_flock64(&ifl, &fl);
719107849Salfred				return fd_truncate(td, uap->fd, &fl);
72043412Snewton			}
72143412Snewton
72243412Snewton		case SVR4_F_REVOKE:
723107849Salfred			return fd_revoke(td, uap->fd);
72443412Snewton
72543412Snewton		default:
72643412Snewton			return ENOSYS;
72743412Snewton		}
72843412Snewton
72943412Snewton	default:
73043412Snewton		return ENOSYS;
73143412Snewton	}
73243412Snewton}
733