Module Name:    src
Committed By:   chs
Date:           Mon Nov 18 01:32:53 UTC 2013

Modified Files:
        src/sys/arch/amd64/include: linux32_machdep.h
        src/sys/compat/linux/arch/amd64: syscalls.master
        src/sys/compat/linux/arch/i386: syscalls.master
        src/sys/compat/linux/common: linux_file.c linux_file64.c linux_misc.c
            linux_misc.h linux_types.h
        src/sys/compat/linux32/arch/amd64: linux32_missing.c syscalls.master
        src/sys/compat/linux32/common: linux32_misc.c linux32_signal.c
            linux32_stat.c

Log Message:
implement the *at() syscalls.
bring the unimplemented syscall list up to date.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/amd64/include/linux32_machdep.h
cvs rdiff -u -r1.44 -r1.45 src/sys/compat/linux/arch/amd64/syscalls.master
cvs rdiff -u -r1.111 -r1.112 src/sys/compat/linux/arch/i386/syscalls.master
cvs rdiff -u -r1.105 -r1.106 src/sys/compat/linux/common/linux_file.c
cvs rdiff -u -r1.53 -r1.54 src/sys/compat/linux/common/linux_file64.c
cvs rdiff -u -r1.227 -r1.228 src/sys/compat/linux/common/linux_misc.c
cvs rdiff -u -r1.23 -r1.24 src/sys/compat/linux/common/linux_misc.h
cvs rdiff -u -r1.30 -r1.31 src/sys/compat/linux/common/linux_types.h
cvs rdiff -u -r1.6 -r1.7 src/sys/compat/linux32/arch/amd64/linux32_missing.c
cvs rdiff -u -r1.63 -r1.64 src/sys/compat/linux32/arch/amd64/syscalls.master
cvs rdiff -u -r1.22 -r1.23 src/sys/compat/linux32/common/linux32_misc.c
cvs rdiff -u -r1.16 -r1.17 src/sys/compat/linux32/common/linux32_signal.c \
    src/sys/compat/linux32/common/linux32_stat.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/amd64/include/linux32_machdep.h
diff -u src/sys/arch/amd64/include/linux32_machdep.h:1.2 src/sys/arch/amd64/include/linux32_machdep.h:1.3
--- src/sys/arch/amd64/include/linux32_machdep.h:1.2	Fri Nov 18 04:09:17 2011
+++ src/sys/arch/amd64/include/linux32_machdep.h	Mon Nov 18 01:32:52 2013
@@ -1,10 +1,11 @@
-/*	$NetBSD: linux32_machdep.h,v 1.2 2011/11/18 04:09:17 christos Exp $ */
+/*	$NetBSD: linux32_machdep.h,v 1.3 2013/11/18 01:32:52 chs Exp $ */
 
 #ifndef _MACHINE_LINUX32_H_
 #define _MACHINE_LINUX32_H_
 
 #include <compat/netbsd32/netbsd32.h>
 
+#include <compat/linux/common/linux_types.h>
 #include <compat/linux32/common/linux32_types.h>
 
 #include <compat/linux32/arch/amd64/linux32_siginfo.h>

Index: src/sys/compat/linux/arch/amd64/syscalls.master
diff -u src/sys/compat/linux/arch/amd64/syscalls.master:1.44 src/sys/compat/linux/arch/amd64/syscalls.master:1.45
--- src/sys/compat/linux/arch/amd64/syscalls.master:1.44	Thu Nov  7 19:37:18 2013
+++ src/sys/compat/linux/arch/amd64/syscalls.master	Mon Nov 18 01:32:52 2013
@@ -1,4 +1,4 @@
-	$NetBSD: syscalls.master,v 1.44 2013/11/07 19:37:18 njoly Exp $
+	$NetBSD: syscalls.master,v 1.45 2013/11/18 01:32:52 chs Exp $
 
 ;	@(#)syscalls.master	8.1 (Berkeley) 7/19/93
 
@@ -67,7 +67,7 @@
 0	NOARGS		{ int|sys||read(int fd, char *buf, u_int nbyte); }
 1	NOARGS		{ int|sys||write(int fd, char *buf, u_int nbyte); }
 2	STD		{ int|linux_sys||open(const char *path, int flags, \
-			    int mode); }
+			    linux_umode_t mode); }
 3	NOARGS		{ int|sys||close(int fd); }
 4	STD		{ int|linux_sys||stat64(const char *path, \
 			    struct linux_stat64 *sp); }
@@ -228,7 +228,7 @@
 81	NOARGS		{ int|sys||fchdir(int fd); }
 82	NOARGS		{ int|sys||__posix_rename(const char *from, \
 			    const char *to); }
-83	NOARGS		{ int|sys||mkdir(const char *path, int mode); }
+83	NOARGS		{ int|sys||mkdir(const char *path, linux_umode_t mode); }
 84	NOARGS		{ int|sys||rmdir(const char *path); }
 85	STD		{ int|linux_sys||creat(const char *path, int mode); }
 86	NOARGS		{ int|sys||link(const char *path, const char *link); }
@@ -236,8 +236,8 @@
 88	NOARGS		{ int|sys||symlink(const char *path, const char *to); }
 89	NOARGS		{ int|sys||readlink(const char *name, char *buf, \
 			    int count); }
-90	NOARGS		{ int|sys||chmod(const char *path, int mode); }
-91	NOARGS		{ int|sys||fchmod(int fd, int mode); }
+90	NOARGS		{ int|sys||chmod(const char *path, linux_umode_t mode); }
+91	NOARGS		{ int|sys||fchmod(int fd, linux_umode_t mode); }
 92	NOARGS		{ int|sys||__posix_chown(const char *path, uid_t uid, \
 				gid_t gid); }
 93	NOARGS		{ int|sys||__posix_fchown(int fd, uid_t uid, \
@@ -300,8 +300,8 @@
 			    struct linux_sigaltstack *oss); }
 132	STD		{ int|linux_sys||utime(const char *path, \
 			    struct linux_utimbuf *times); }
-133	STD		{ int|linux_sys||mknod(const char *path, int mode, \
-			    int dev); }
+133	STD		{ int|linux_sys||mknod(const char *path, linux_umode_t mode, \
+			    unsigned dev); }
 #ifdef EXEC_AOUT
 134	STD		{ int|linux_sys||uselib(const char *path); }
 #else
@@ -462,19 +462,31 @@
 254	UNIMPL		inotify_add_watch
 255	UNIMPL		inotify_rm_watch
 256	UNIMPL		migrate_pages
-257	UNIMPL		openat
-258	UNIMPL		mkdirat
-259	UNIMPL		mknodat
-260	UNIMPL		fchownat
+257	STD 		{ int|linux_sys||openat(int fd, const char *path, \
+			    int flags, ... linux_umode_t mode); }
+258	NOARGS		{ int|sys||mkdirat(int fd, const char *path, \
+			    linux_umode_t mode); }
+259	STD		{ int|linux_sys||mknodat(int fd, const char *path, \
+			    linux_umode_t mode, unsigned dev); }
+260	STD		{ int|linux_sys||fchownat(int fd, const char *path, \
+			    uid_t owner, gid_t group, int flag); }
 261	UNIMPL		futimesat
-262	UNIMPL		newfstatat
-263	UNIMPL		unlinkat
-264	UNIMPL		renameat
-265	UNIMPL		linkat
-266	UNIMPL		symlinkat
-267	UNIMPL		readlinkat
-268	UNIMPL		fchmodat
-269	UNIMPL		faccessat
+262	STD		{ int|linux_sys||fstatat64(int fd, const char *path, \
+			    struct linux_stat *sp, int flag); }
+263	STD		{ int|linux_sys||unlinkat(int fd, const char *path, \
+			    int flag); }
+264	NOARGS		{ int|sys||renameat(int fromfd, const char *from, \
+			    int tofd, const char *to); }
+265	STD		{ int|linux_sys||linkat(int fd1, const char *name1, \
+			    int fd2, const char *name2, int flags); }
+266	NOARGS		{ int|sys||symlinkat(const char *path1, int fd, \
+			    const char *path2); }
+267	NOARGS		{ int|sys||readlinkat(int fd, const char *path, \
+			    char *buf, size_t bufsize); }
+268	STD		{ int|linux_sys||fchmodat(int fd, const char *path, \
+			    linux_umode_t mode); }
+269	STD		{ int|linux_sys||faccessat(int fd, const char *path, \
+			    int amode); }
 270	UNIMPL		pselect6
 271	STD		{ int|linux_sys||ppoll(struct pollfd *fds, int nfds, \
 			    struct linux_timespec *timeout, \
@@ -511,6 +523,20 @@
 297	UNIMPL		rt_tgsigqueueinfo
 298	UNIMPL		perf_counter_open
 299	UNIMPL		recvmmsg
+300	UNIMPL		fanotify_init
+301	UNIMPL		fanotify_mark
+302	UNIMPL		prlimit64
+303	UNIMPL		name_to_handle_at
+304	UNIMPL		open_by_handle_at
+305	UNIMPL		clock_adjtime
+306	UNIMPL		syncfs
+307	UNIMPL		sendmmsg
+308	UNIMPL		setns
+309	UNIMPL		getcpu
+310	UNIMPL		process_vm_readv
+311	UNIMPL		process_vm_writev
+312	UNIMPL		kcmp
+313	UNIMPL		finit_module
 
 ; we want a "nosys" syscall, we'll just add an extra entry for it.
-300	STD		{ int|linux_sys||nosys(void); }
+314	STD		{ int|linux_sys||nosys(void); }

Index: src/sys/compat/linux/arch/i386/syscalls.master
diff -u src/sys/compat/linux/arch/i386/syscalls.master:1.111 src/sys/compat/linux/arch/i386/syscalls.master:1.112
--- src/sys/compat/linux/arch/i386/syscalls.master:1.111	Thu Nov  7 19:37:18 2013
+++ src/sys/compat/linux/arch/i386/syscalls.master	Mon Nov 18 01:32:52 2013
@@ -1,4 +1,4 @@
-	$NetBSD: syscalls.master,v 1.111 2013/11/07 19:37:18 njoly Exp $
+	$NetBSD: syscalls.master,v 1.112 2013/11/18 01:32:52 chs Exp $
 
 ;	@(#)syscalls.master	8.1 (Berkeley) 7/19/93
 
@@ -58,20 +58,20 @@
 3	NOARGS		{ int|sys||read(int fd, char *buf, u_int nbyte); }
 4	NOARGS		{ int|sys||write(int fd, char *buf, u_int nbyte); }
 5	STD		{ int|linux_sys||open(const char *path, int flags, \
-			    int mode); }
+			    linux_umode_t mode); }
 6	NOARGS		{ int|sys||close(int fd); }
 7	STD		{ int|linux_sys||waitpid(int pid, int *status, \
 			    int options);}
-8	STD		{ int|linux_sys||creat(const char *path, int mode); }
+8	STD		{ int|linux_sys||creat(const char *path, linux_umode_t mode); }
 9	NOARGS		{ int|sys||link(const char *path, const char *link); }
 10	STD		{ int|linux_sys||unlink(const char *path); }
 11	NOARGS		{ int|sys||execve(const char *path, char **argp, \
 			    char **envp); }
 12	NOARGS		{ int|sys||chdir(const char *path); }
 13	STD		{ int|linux_sys||time(linux_time_t *t); }
-14	STD		{ int|linux_sys||mknod(const char *path, int mode, \
-			    int dev); }
-15	NOARGS		{ int|sys||chmod(const char *path, int mode); }
+14	STD		{ int|linux_sys||mknod(const char *path, linux_umode_t mode, \
+			    unsigned dev); }
+15	NOARGS		{ int|sys||chmod(const char *path, linux_umode_t mode); }
 16	STD		{ int|linux_sys||lchown16(const char *path, \
 			    linux_uid16_t uid, linux_gid16_t gid); }
 ;17 - no longer in linux source.
@@ -101,7 +101,7 @@
 37	STD		{ int|linux_sys||kill(int pid, int signum); }
 38	NOARGS		{ int|sys||__posix_rename(const char *from, \
 			    const char *to); }
-39	NOARGS		{ int|sys||mkdir(const char *path, int mode); }
+39	NOARGS		{ int|sys||mkdir(const char *path, linux_umode_t mode); }
 40	NOARGS		{ int|sys||rmdir(const char *path); }
 41	NOARGS		{ int|sys||dup(int fd); }
 42	STD		{ int|linux_sys||pipe(int *pfds); }
@@ -181,7 +181,7 @@
 92	NOARGS		{ int|compat_43_sys||truncate(const char *path, \
 			    long length); }
 93	NOARGS		{ int|compat_43_sys||ftruncate(int fd, long length); }
-94	NOARGS		{ int|sys||fchmod(int fd, int mode); }
+94	NOARGS		{ int|sys||fchmod(int fd, linux_umode_t mode); }
 95	STD		{ int|linux_sys||fchown16(int fd, linux_uid16_t uid, \
 			    linux_gid16_t gid); }
 96	STD		{ int|linux_sys||getpriority(int which, int who); }
@@ -476,19 +476,31 @@
 292	UNIMPL		inotify_add_watch
 293	UNIMPL		inotify_rm_watch
 294	UNIMPL		migrate_pages
-295	UNIMPL		openat
-296	UNIMPL		mkdirat
-297	UNIMPL		mknodat
-298	UNIMPL		fchownat
+295	STD 		{ int|linux_sys||openat(int fd, const char *path, \
+			    int flags, ... linux_umode_t mode); }
+296	NOARGS		{ int|sys||mkdirat(int fd, const char *path, \
+			    linux_umode_t mode); }
+297	STD		{ int|linux_sys||mknodat(int fd, const char *path, \
+			    linux_umode_t mode, unsigned dev); }
+298	STD		{ int|linux_sys||fchownat(int fd, const char *path, \
+			    uid_t owner, gid_t group, int flag); }
 299	UNIMPL		futimesat
-300	UNIMPL		fstatat64
-301	UNIMPL		unlinkat
-302	UNIMPL		renameat
-303	UNIMPL		linkat
-304	UNIMPL		symlinkat
-305	UNIMPL		readlinkat
-306	UNIMPL		fchmodat
-307	UNIMPL		faccessat
+300	STD		{ int|linux_sys||fstatat64(int fd, const char *path, \
+			    struct linux_stat64 *sp, int flag); }
+301	STD		{ int|linux_sys||unlinkat(int fd, const char *path, \
+			    int flag); }
+302	NOARGS		{ int|sys||renameat(int fromfd, const char *from, \
+			    int tofd, const char *to); }
+303	STD		{ int|linux_sys||linkat(int fd1, const char *name1, \
+			    int fd2, const char *name2, int flags); }
+304	NOARGS		{ int|sys||symlinkat(const char *path1, int fd, \
+			    const char *path2); }
+305	NOARGS		{ int|sys||readlinkat(int fd, const char *path, \
+			    char *buf, size_t bufsize); }
+306	STD		{ int|linux_sys||fchmodat(int fd, const char *path, \
+			    linux_umode_t mode); }
+307	STD		{ int|linux_sys||faccessat(int fd, const char *path, \
+			    int amode); }
 308	UNIMPL		pselect6
 309	STD		{ int|linux_sys||ppoll(struct pollfd *fds, int nfds, \
 			    struct linux_timespec *timeout, \
@@ -525,3 +537,16 @@
 335	UNIMPL		rt_tgsigqueueinfo
 336	UNIMPL		perf_counter_open
 337	UNIMPL		recvmmsg
+338	UNIMPL		fanotify_init
+339	UNIMPL		fanotify_mark
+340	UNIMPL		prlimit64
+341	UNIMPL		name_to_handle_at
+342	UNIMPL		open_by_handle_at
+343	UNIMPL		clock_adjtime
+344	UNIMPL		syncfs
+345	UNIMPL		sendmmsg
+346	UNIMPL		setns
+347	UNIMPL		process_vm_readv
+348	UNIMPL		process_vm_writev
+349	UNIMPL		kcmp
+350	UNIMPL		finit_module

Index: src/sys/compat/linux/common/linux_file.c
diff -u src/sys/compat/linux/common/linux_file.c:1.105 src/sys/compat/linux/common/linux_file.c:1.106
--- src/sys/compat/linux/common/linux_file.c:1.105	Tue Sep 24 13:27:50 2013
+++ src/sys/compat/linux/common/linux_file.c	Mon Nov 18 01:32:52 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux_file.c,v 1.105 2013/09/24 13:27:50 njoly Exp $	*/
+/*	$NetBSD: linux_file.c,v 1.106 2013/11/18 01:32:52 chs Exp $	*/
 
 /*-
  * Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_file.c,v 1.105 2013/09/24 13:27:50 njoly Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_file.c,v 1.106 2013/11/18 01:32:52 chs Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -155,6 +155,32 @@ linux_sys_creat(struct lwp *l, const str
 	return sys_open(l, &oa, retval);
 }
 
+static void
+linux_open_ctty(struct lwp *l, int flags, int fd)
+{
+	struct proc *p = l->l_proc;
+
+	/*
+	 * this bit from sunos_misc.c (and svr4_fcntl.c).
+	 * If we are a session leader, and we don't have a controlling
+	 * terminal yet, and the O_NOCTTY flag is not set, try to make
+	 * this the controlling terminal.
+	 */
+        if (!(flags & O_NOCTTY) && SESS_LEADER(p) && !(p->p_lflag & PL_CONTROLT)) {
+                file_t *fp;
+
+		fp = fd_getfile(fd);
+
+                /* ignore any error, just give it a try */
+                if (fp != NULL) {
+			if (fp->f_type == DTYPE_VNODE) {
+				(fp->f_ops->fo_ioctl) (fp, TIOCSCTTY, NULL);
+			}
+			fd_putfile(fd);
+		}
+        }
+}
+
 /*
  * open(2). Take care of the different flag values, and let the
  * NetBSD syscall do the real work. See if this operation
@@ -169,7 +195,6 @@ linux_sys_open(struct lwp *l, const stru
 		syscallarg(int) flags;
 		syscallarg(int) mode;
 	} */
-	struct proc *p = l->l_proc;
 	int error, fl;
 	struct sys_open_args boa;
 
@@ -182,25 +207,32 @@ linux_sys_open(struct lwp *l, const stru
 	if ((error = sys_open(l, &boa, retval)))
 		return error;
 
-	/*
-	 * this bit from sunos_misc.c (and svr4_fcntl.c).
-	 * If we are a session leader, and we don't have a controlling
-	 * terminal yet, and the O_NOCTTY flag is not set, try to make
-	 * this the controlling terminal.
-	 */
-        if (!(fl & O_NOCTTY) && SESS_LEADER(p) && !(p->p_lflag & PL_CONTROLT)) {
-                file_t *fp;
+	linux_open_ctty(l, fl, *retval);
+	return 0;
+}
 
-		fp = fd_getfile(*retval);
+int
+linux_sys_openat(struct lwp *l, const struct linux_sys_openat_args *uap, register_t *retval)
+{
+	/* {
+		syscallarg(const char *) path;
+		syscallarg(int) flags;
+		syscallarg(int) mode;
+	} */
+	int error, fl;
+	struct sys_openat_args boa;
 
-                /* ignore any error, just give it a try */
-                if (fp != NULL) {
-			if (fp->f_type == DTYPE_VNODE) {
-				(fp->f_ops->fo_ioctl) (fp, TIOCSCTTY, NULL);
-			}
-			fd_putfile(*retval);
-		}
-        }
+	fl = linux_to_bsd_ioflags(SCARG(uap, flags));
+
+	SCARG(&boa, fd) = SCARG(uap, fd);
+	SCARG(&boa, path) = SCARG(uap, path);
+	SCARG(&boa, oflags) = fl;
+	SCARG(&boa, mode) = SCARG(uap, mode);
+
+	if ((error = sys_openat(l, &boa, retval)))
+		return error;
+
+	linux_open_ctty(l, fl, *retval);
 	return 0;
 }
 
@@ -492,19 +524,34 @@ linux_sys_lstat(struct lwp *l, const str
 /*
  * The following syscalls are mostly here because of the alternate path check.
  */
+
 int
-linux_sys_unlink(struct lwp *l, const struct linux_sys_unlink_args *uap, register_t *retval)
+linux_sys_linkat(struct lwp *l, const struct linux_sys_linkat_args *uap, register_t *retval)
 {
 	/* {
-		syscallarg(const char *) path;
+		syscallarg(int) fd1;
+		syscallarg(const char *) name1;
+		syscallarg(int) fd2;
+		syscallarg(const char *) name2;
+		syscallarg(int) flags;
 	} */
-	int error, error2;
-	struct pathbuf *pb;
-	struct nameidata nd;
+	int fd1 = SCARG(uap, fd1);
+	const char *name1 = SCARG(uap, name1);
+	int fd2 = SCARG(uap, fd2);
+	const char *name2 = SCARG(uap, name2);
+	int follow;
 
-	error = sys_unlink(l, (const void *)uap, retval);
-	if (error != EPERM)
-		return (error);
+	follow = SCARG(uap, flags) & LINUX_AT_SYMLINK_FOLLOW;
+
+	return do_sys_linkat(l, fd1, name1, fd2, name2, follow, retval);
+}
+
+static int
+linux_unlink_dircheck(const char *path)
+{
+	struct nameidata nd;
+	struct pathbuf *pb;
+	int error;
 
 	/*
 	 * Linux returns EISDIR if unlink(2) is called on a directory.
@@ -514,9 +561,9 @@ linux_sys_unlink(struct lwp *l, const st
 	 *
 	 * XXX this should really not copy in the path buffer twice...
 	 */
-	error2 = pathbuf_copyin(SCARG(uap, path), &pb);
-	if (error2) {
-		return error2;
+	error = pathbuf_copyin(path, &pb);
+	if (error) {
+		return error;
 	}
 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | TRYEMULROOT, pb);
 	if (namei(&nd) == 0) {
@@ -529,8 +576,44 @@ linux_sys_unlink(struct lwp *l, const st
 		vput(nd.ni_vp);
 	}
 	pathbuf_destroy(pb);
+	return error ? error : EPERM;
+}
 
-	return (error);
+int
+linux_sys_unlink(struct lwp *l, const struct linux_sys_unlink_args *uap, register_t *retval)
+{
+	/* {
+		syscallarg(const char *) path;
+	} */
+	int error;
+
+	error = sys_unlink(l, (const void *)uap, retval);
+	if (error == EPERM)
+		error = linux_unlink_dircheck(SCARG(uap, path));
+
+	return error;
+}
+
+int
+linux_sys_unlinkat(struct lwp *l, const struct linux_sys_unlinkat_args *uap, register_t *retval)
+{
+	/* {
+		syscallarg(int) fd;
+		syscallarg(const char *) path;
+		syscallarg(int) flag;
+	} */
+	struct sys_unlinkat_args ua;
+	int error;
+
+	SCARG(&ua, fd) = SCARG(uap, fd);
+	SCARG(&ua, path) = SCARG(uap, path);
+	SCARG(&ua, flag) = linux_to_bsd_atflags(SCARG(uap, flag));
+
+	error = sys_unlinkat(l, &ua, retval);
+	if (error == EPERM)
+		error = linux_unlink_dircheck(SCARG(uap, path));
+
+	return error;
 }
 
 int
@@ -538,19 +621,39 @@ linux_sys_mknod(struct lwp *l, const str
 {
 	/* {
 		syscallarg(const char *) path;
-		syscallarg(int) mode;
-		syscallarg(int) dev;
+		syscallarg(linux_umode_t) mode;
+		syscallarg(unsigned) dev;
+	} */
+	struct linux_sys_mknodat_args ua;
+
+	SCARG(&ua, fd) = LINUX_AT_FDCWD;
+	SCARG(&ua, path) = SCARG(uap, path);
+	SCARG(&ua, mode) = SCARG(uap, mode);
+	SCARG(&ua, dev) = SCARG(uap, dev);
+
+	return linux_sys_mknodat(l, &ua, retval);
+}
+
+int
+linux_sys_mknodat(struct lwp *l, const struct linux_sys_mknodat_args *uap, register_t *retval)
+{
+	/* {
+		syscallarg(int) fd;
+		syscallarg(const char *) path;
+		syscallarg(linux_umode_t) mode;
+		syscallarg(unsigned) dev;
 	} */
 
 	/*
 	 * BSD handles FIFOs separately
 	 */
 	if (S_ISFIFO(SCARG(uap, mode))) {
-		struct sys_mkfifo_args bma;
+		struct sys_mkfifoat_args bma;
 
+		SCARG(&bma, fd) = SCARG(uap, fd);
 		SCARG(&bma, path) = SCARG(uap, path);
 		SCARG(&bma, mode) = SCARG(uap, mode);
-		return sys_mkfifo(l, &bma, retval);
+		return sys_mkfifoat(l, &bma, retval);
 	} else {
 
 		/*
@@ -559,11 +662,56 @@ linux_sys_mknod(struct lwp *l, const str
 		 * this just fits into our dev_t. Just mask off the
 		 * upper 16bit to remove any random junk.
 		 */
-		return do_sys_mknod(l, SCARG(uap, path), SCARG(uap, mode),
-		    SCARG(uap, dev) & 0xffff, retval, UIO_USERSPACE);
+
+		return do_sys_mknodat(l, SCARG(uap, fd), SCARG(uap, path),
+		    SCARG(uap, mode), SCARG(uap, dev) & 0xffff, retval,
+		    UIO_USERSPACE);
 	}
 }
 
+int
+linux_sys_fchmodat(struct lwp *l, const struct linux_sys_fchmodat_args *uap, register_t *retval)
+{
+	/* {
+		syscallarg(int) fd;
+		syscallarg(const char *) path;
+		syscallarg(linux_umode_t) mode;
+	} */
+
+	return do_sys_chmodat(l, SCARG(uap, fd), SCARG(uap, path),
+			      SCARG(uap, mode), AT_SYMLINK_FOLLOW);
+}
+
+int
+linux_sys_fchownat(struct lwp *l, const struct linux_sys_fchownat_args *uap, register_t *retval)
+{
+	/* {
+		syscallarg(int) fd;
+		syscallarg(const char *) path;
+		syscallarg(uid_t) owner;
+		syscallarg(gid_t) group;
+		syscallarg(int) flag;
+	} */
+	int flag;
+
+	flag = linux_to_bsd_atflags(SCARG(uap, flag));
+	return do_sys_chownat(l, SCARG(uap, fd), SCARG(uap, path),
+			      SCARG(uap, owner), SCARG(uap, group), flag);
+}
+
+int
+linux_sys_faccessat(struct lwp *l, const struct linux_sys_faccessat_args *uap, register_t *retval)
+{
+	/* {
+		syscallarg(int) fd;
+		syscallarg(const char *) path;
+		syscallarg(int) amode;
+	} */
+
+	return do_sys_accessat(l, SCARG(uap, fd), SCARG(uap, path),
+	     SCARG(uap, amode), AT_SYMLINK_FOLLOW);
+}
+
 /*
  * This is just fsync() for now (just as it is in the Linux kernel)
  * Note: this is not implemented under Linux on Alpha and Arm

Index: src/sys/compat/linux/common/linux_file64.c
diff -u src/sys/compat/linux/common/linux_file64.c:1.53 src/sys/compat/linux/common/linux_file64.c:1.54
--- src/sys/compat/linux/common/linux_file64.c:1.53	Fri Oct 14 09:23:28 2011
+++ src/sys/compat/linux/common/linux_file64.c	Mon Nov 18 01:32:52 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux_file64.c,v 1.53 2011/10/14 09:23:28 hannken Exp $	*/
+/*	$NetBSD: linux_file64.c,v 1.54 2013/11/18 01:32:52 chs Exp $	*/
 
 /*-
  * Copyright (c) 1995, 1998, 2000, 2008 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_file64.c,v 1.53 2011/10/14 09:23:28 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_file64.c,v 1.54 2013/11/18 01:32:52 chs Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -171,6 +171,33 @@ linux_sys_lstat64(struct lwp *l, const s
 }
 
 int
+linux_sys_fstatat64(struct lwp *l, const struct linux_sys_fstatat64_args *uap, register_t *retval)
+{
+	/* {
+		syscallarg(int) fd;
+		syscallarg(const char *) path;
+		syscallarg(struct linux_stat64 *) sp;
+		syscallarg(int) flag;
+	} */
+	struct linux_stat64 tmplst;
+	struct stat tmpst;
+	int error, nd_flag;
+
+	if (SCARG(uap, flag) & LINUX_AT_SYMLINK_NOFOLLOW)
+		nd_flag = NOFOLLOW;
+	else
+		nd_flag = FOLLOW;
+
+	error = do_sys_statat(l, SCARG(uap, fd), SCARG(uap, path), nd_flag, &tmpst);
+	if (error != 0)
+		return error;
+
+	bsd_to_linux_stat(&tmpst, &tmplst);
+
+	return copyout(&tmplst, SCARG(uap, sp), sizeof tmplst);
+}
+
+int
 linux_sys_truncate64(struct lwp *l, const struct linux_sys_truncate64_args *uap, register_t *retval)
 {
 	/* {

Index: src/sys/compat/linux/common/linux_misc.c
diff -u src/sys/compat/linux/common/linux_misc.c:1.227 src/sys/compat/linux/common/linux_misc.c:1.228
--- src/sys/compat/linux/common/linux_misc.c:1.227	Sun Nov 10 12:07:52 2013
+++ src/sys/compat/linux/common/linux_misc.c	Mon Nov 18 01:32:52 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux_misc.c,v 1.227 2013/11/10 12:07:52 slp Exp $	*/
+/*	$NetBSD: linux_misc.c,v 1.228 2013/11/18 01:32:52 chs Exp $	*/
 
 /*-
  * Copyright (c) 1995, 1998, 1999, 2008 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_misc.c,v 1.227 2013/11/10 12:07:52 slp Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_misc.c,v 1.228 2013/11/18 01:32:52 chs Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -113,10 +113,8 @@ __KERNEL_RCSID(0, "$NetBSD: linux_misc.c
 #include <compat/linux/common/linux_dirent.h>
 #include <compat/linux/common/linux_util.h>
 #include <compat/linux/common/linux_misc.h>
-#ifndef COMPAT_LINUX32
 #include <compat/linux/common/linux_statfs.h>
 #include <compat/linux/common/linux_limit.h>
-#endif
 #include <compat/linux/common/linux_ptrace.h>
 #include <compat/linux/common/linux_reboot.h>
 #include <compat/linux/common/linux_emuldata.h>
@@ -124,7 +122,6 @@ __KERNEL_RCSID(0, "$NetBSD: linux_misc.c
 
 #include <compat/linux/linux_syscallargs.h>
 
-#ifndef COMPAT_LINUX32
 const int linux_ptrace_request_map[] = {
 	LINUX_PTRACE_TRACEME,	PT_TRACE_ME,
 	LINUX_PTRACE_PEEKTEXT,	PT_READ_I,
@@ -1411,74 +1408,50 @@ linux_sys_utimes(struct lwp *l, const st
 }
 
 int
-linux_sys_utimensat(struct lwp *l, const struct linux_sys_utimensat_args *uap,
-	register_t *retval)
+linux_do_sys_utimensat(struct lwp *l, int fd, const char *path, struct timespec *tsp, int flags, register_t *retval)
 {
-	/* {
-		syscallarg(int) fd;
-		syscallarg(const char *) path;
-		syscallarg(const struct linux_timespec *) times;
-		syscallarg(int) flag;
-	} */
 	int follow, error;
-	struct linux_timespec lts[2];
-	struct timespec *tsp = NULL, ts[2];
 
-	follow = (SCARG(uap, flag) & LINUX_AT_SYMLINK_NOFOLLOW) ?
-	    NOFOLLOW : FOLLOW;
+	follow = (flags & LINUX_AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW;
 
-	if (SCARG(uap, times)) {
-		error = copyin(SCARG(uap, times), &lts, sizeof(lts));
-		if (error != 0)
-			return error;
-		linux_to_native_timespec(&ts[0], &lts[0]);
-		linux_to_native_timespec(&ts[1], &lts[1]);
-		tsp = ts;
-	}
-
-	if (SCARG(uap, path) == NULL && SCARG(uap, fd) != AT_FDCWD) {
+	if (path == NULL && fd != AT_FDCWD) {
 		file_t *fp;
 
 		/* fd_getvnode() will use the descriptor for us */
-		if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
+		if ((error = fd_getvnode(fd, &fp)) != 0)
 			return error;
 		error = do_sys_utimensat(l, AT_FDCWD, fp->f_data, NULL, 0,
 		    tsp, UIO_SYSSPACE);
-		fd_putfile(SCARG(uap, fd));
+		fd_putfile(fd);
 		return error;
 	}
 
-	return do_sys_utimensat(l, SCARG(uap, fd), NULL,
-	    SCARG(uap, path), follow, tsp, UIO_SYSSPACE);
-
+	return do_sys_utimensat(l, fd, NULL, path, follow, tsp, UIO_SYSSPACE);
 }
 
-int linux_sys_lutimes(struct lwp *, const struct linux_sys_utimes_args *, register_t *);
 int
-linux_sys_lutimes(struct lwp *l, const struct linux_sys_utimes_args *uap, register_t *retval)
+linux_sys_utimensat(struct lwp *l, const struct linux_sys_utimensat_args *uap,
+	register_t *retval)
 {
 	/* {
+		syscallarg(int) fd;
 		syscallarg(const char *) path;
-		syscallarg(const struct linux_timeval) *times;
+		syscallarg(const struct linux_timespec *) times;
+		syscallarg(int) flag;
 	} */
-	struct linux_timeval ltv[2];
-	struct timeval tv[2];
-	struct timeval *tptr = NULL;
 	int error;
+	struct linux_timespec lts[2];
+	struct timespec *tsp = NULL, ts[2];
 
 	if (SCARG(uap, times)) {
-		if ((error = copyin(SCARG(uap, times), &ltv, sizeof(ltv))))
+		error = copyin(SCARG(uap, times), &lts, sizeof(lts));
+		if (error != 0)
 			return error;
-
-		tv[0].tv_sec = ltv[0].tv_sec;
-		tv[0].tv_usec = ltv[0].tv_usec;
-		tv[1].tv_sec = ltv[1].tv_sec;
-		tv[1].tv_usec = ltv[1].tv_usec;
-
-		tptr = tv;
+		linux_to_native_timespec(&ts[0], &lts[0]);
+		linux_to_native_timespec(&ts[1], &lts[1]);
+		tsp = ts;
 	}
 
-	return do_sys_utimes(l, NULL, SCARG(uap, path), NOFOLLOW,
-	    tptr, UIO_SYSSPACE);
+	return linux_do_sys_utimensat(l, SCARG(uap, fd), SCARG(uap, path),
+	    tsp, SCARG(uap, flag), retval);
 }
-#endif /* !COMPAT_LINUX32 */

Index: src/sys/compat/linux/common/linux_misc.h
diff -u src/sys/compat/linux/common/linux_misc.h:1.23 src/sys/compat/linux/common/linux_misc.h:1.24
--- src/sys/compat/linux/common/linux_misc.h:1.23	Sat Sep 22 22:34:02 2012
+++ src/sys/compat/linux/common/linux_misc.h	Mon Nov 18 01:32:52 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux_misc.h,v 1.23 2012/09/22 22:34:02 joerg Exp $	*/
+/*	$NetBSD: linux_misc.h,v 1.24 2013/11/18 01:32:52 chs Exp $	*/
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -144,6 +144,8 @@ __BEGIN_DECLS
 int bsd_to_linux_wstat(int);
 int linux_select1(struct lwp *, register_t *, int, fd_set *, fd_set *,
 		       fd_set *, struct linux_timeval *);
+int linux_do_sys_utimensat(struct lwp *, int, const char *,
+    struct timespec *, int, register_t *);
 __END_DECLS
 #endif /* !_KERNEL */
 

Index: src/sys/compat/linux/common/linux_types.h
diff -u src/sys/compat/linux/common/linux_types.h:1.30 src/sys/compat/linux/common/linux_types.h:1.31
--- src/sys/compat/linux/common/linux_types.h:1.30	Sun Jan 11 02:45:48 2009
+++ src/sys/compat/linux/common/linux_types.h	Mon Nov 18 01:32:52 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux_types.h,v 1.30 2009/01/11 02:45:48 christos Exp $	*/
+/*	$NetBSD: linux_types.h,v 1.31 2013/11/18 01:32:52 chs Exp $	*/
 
 /*-
  * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
@@ -54,6 +54,7 @@ typedef long linux_suseconds_t;
 
 typedef unsigned short linux_gid16_t;
 typedef unsigned short linux_uid16_t;
+typedef unsigned short linux_umode_t;
 
 /*
  * From Linux include/asm-.../posix_types.h

Index: src/sys/compat/linux32/arch/amd64/linux32_missing.c
diff -u src/sys/compat/linux32/arch/amd64/linux32_missing.c:1.6 src/sys/compat/linux32/arch/amd64/linux32_missing.c:1.7
--- src/sys/compat/linux32/arch/amd64/linux32_missing.c:1.6	Wed Nov 19 18:36:04 2008
+++ src/sys/compat/linux32/arch/amd64/linux32_missing.c	Mon Nov 18 01:32:52 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux32_missing.c,v 1.6 2008/11/19 18:36:04 ad Exp $ */
+/*	$NetBSD: linux32_missing.c,v 1.7 2013/11/18 01:32:52 chs Exp $ */
 
 #include <sys/cdefs.h>
 
@@ -25,8 +25,8 @@
 
 #include <compat/linux/common/linux_ipc.h>
 #include <compat/linux/common/linux_sem.h>
+
 #include <compat/linux/common/linux_fcntl64.c>
 #include <compat/linux/common/linux_llseek.c>
 #include <compat/linux/common/linux_misc_notalpha.c>
-#include <compat/linux/common/linux_misc.c>
 #include <compat/linux/common/linux_uid16.c>

Index: src/sys/compat/linux32/arch/amd64/syscalls.master
diff -u src/sys/compat/linux32/arch/amd64/syscalls.master:1.63 src/sys/compat/linux32/arch/amd64/syscalls.master:1.64
--- src/sys/compat/linux32/arch/amd64/syscalls.master:1.63	Thu Nov  7 19:37:19 2013
+++ src/sys/compat/linux32/arch/amd64/syscalls.master	Mon Nov 18 01:32:52 2013
@@ -1,4 +1,4 @@
-	$NetBSD: syscalls.master,v 1.63 2013/11/07 19:37:19 njoly Exp $
+	$NetBSD: syscalls.master,v 1.64 2013/11/18 01:32:52 chs Exp $
 
 ; NetBSD i386 COMPAT_LINUX32 system call name/number "master" file.
 ; (See syscalls.conf to see what it is processed into.)
@@ -43,12 +43,13 @@
 #include <compat/netbsd32/netbsd32.h>
 #include <compat/netbsd32/netbsd32_syscallargs.h>
 
+#include <compat/linux/common/linux_types.h>
+
 #include <compat/linux32/common/linux32_types.h>
 #include <compat/linux32/common/linux32_signal.h>
 #include <compat/linux32/arch/amd64/linux32_missing.h>
 #include <compat/linux32/linux32_syscallargs.h>
 
-#include <compat/linux/common/linux_types.h>
 #include <compat/linux/common/linux_mmap.h>
 #include <compat/linux/common/linux_signal.h>
 #include <compat/linux/common/linux_siginfo.h>
@@ -67,11 +68,11 @@
 4	NOARGS	{ netbsd32_ssize_t|netbsd32||write(int fd, \
 		    netbsd32_voidp buf, netbsd32_size_t nbyte); }
 5	STD	{ int|linux32_sys||open(netbsd32_charp path, int flags, \
-		    int mode); }
+		    linux_umode_t mode); }
 6	NOARGS	{ int|netbsd32||close(int fd); }
 7	STD	{ int|linux32_sys||waitpid(int pid, netbsd32_intp status, \
 		    int options);}
-8	STD	{ int|linux32_sys||creat(netbsd32_charp path, int mode); }
+8	STD	{ int|linux32_sys||creat(netbsd32_charp path, linux_umode_t mode); }
 9	NOARGS	{ int|netbsd32||link(netbsd32_charp path, \
 		    netbsd32_charp link); }
 10	STD	{ int|linux32_sys||unlink(netbsd32_charp path); }
@@ -80,8 +81,8 @@
 12	NOARGS	{ int|netbsd32||chdir(netbsd32_charp path); }
 13	STD	{ int|linux32_sys||time(linux32_timep_t t); }
 14	STD	{ int|linux32_sys||mknod(netbsd32_charp path, \
-		    int mode, int dev); }
-15	NOARGS	{ int|netbsd32||chmod(netbsd32_charp path, int mode); }
+		    linux_umode_t mode, unsigned dev); }
+15	NOARGS	{ int|netbsd32||chmod(netbsd32_charp path, linux_umode_t mode); }
 16	STD	{ int|linux32_sys||lchown16(netbsd32_charp path, \
 		    linux32_uid16_t uid, linux32_gid16_t gid); }
 17	STD	{ int|linux32_sys||break(netbsd32_charp nsize); }
@@ -111,7 +112,7 @@
 37	STD	{ int|linux32_sys||kill(int pid, int signum); }
 38	NOARGS	{ int|netbsd32||__posix_rename(netbsd32_charp from, \
 		    netbsd32_charp to); }
-39	NOARGS	{ int|netbsd32||mkdir(netbsd32_charp path, int mode); }
+39	NOARGS	{ int|netbsd32||mkdir(netbsd32_charp path, linux_umode_t mode); }
 40	NOARGS	{ int|netbsd32||rmdir(netbsd32_charp path); }
 41	NOARGS	{ int|netbsd32||dup(int fd); }
 42	STD	{ int|linux32_sys||pipe(netbsd32_intp fd); }
@@ -188,7 +189,7 @@
 		    netbsd32_long length); }
 93	NOARGS	{ int|compat_43_netbsd32||oftruncate(int fd, \
 		    netbsd32_long length); }
-94	NOARGS	{ int|netbsd32||fchmod(int fd, int mode); }
+94	NOARGS	{ int|netbsd32||fchmod(int fd, linux_umode_t mode); }
 95	STD	{ int|linux32_sys||fchown16(int fd, linux32_uid16_t uid, \
 		    linux32_gid16_t gid); }
 96	STD	{ int|linux32_sys||getpriority(int which, int who); }
@@ -490,19 +491,31 @@
 292	UNIMPL	inotify_add_watch
 293	UNIMPL	inotify_rm_watch
 294	UNIMPL	migrate_pages
-295	UNIMPL	openat
-296	UNIMPL	mkdirat
-297	UNIMPL	mknodat
-298	UNIMPL	fchownat
+295	STD	{ int|linux32_sys||openat(int fd, netbsd32_charp path, \
+		    int flags, ... linux_umode_t mode); }
+296	NOARGS	{ int|netbsd32||mkdirat(int fd, netbsd32_charp path, \
+		    linux_umode_t mode); }
+297	STD	{ int|linux32_sys||mknodat(int fd, netbsd32_charp path, \
+		    linux_umode_t mode, unsigned dev); }
+298	STD	{ int|linux32_sys||fchownat(int fd, netbsd32_charp path, \
+		    uid_t owner, gid_t group, int flag); }
 299	UNIMPL	futimesat
-300	UNIMPL	fstatat64
-301	UNIMPL	unlinkat
-302	UNIMPL	renameat
-303	UNIMPL	linkat
-304	UNIMPL	symlinkat
-305	UNIMPL	readlinkat
-306	UNIMPL	fchmodat
-307	UNIMPL	faccessat
+300	STD	{ int|linux32_sys||fstatat64(int fd, netbsd32_charp path, \
+		    linux32_stat64p sp, int flag); }
+301	STD	{ int|linux32_sys||unlinkat(int fd, netbsd32_charp path, \
+		    int flag); }
+302	NOARGS	{ int|netbsd32||renameat(int fromfd, netbsd32_charp from, \
+		    int tofd, netbsd32_charp to); }
+303	STD	{ int|linux32_sys||linkat(int fd1, netbsd32_charp name1, \
+		    int fd2, netbsd32_charp name2, int flags); }
+304	NOARGS	{ int|netbsd32||symlinkat(netbsd32_charp path1, int fd, \
+		    netbsd32_charp path2); }
+305	NOARGS	{ int|netbsd32||readlinkat(int fd, netbsd32_charp path, \
+		    netbsd32_charp buf, linux32_size_t bufsize); }
+306	STD	{ int|linux32_sys||fchmodat(int fd, netbsd32_charp path, \
+		    linux_umode_t mode); }
+307	STD	{ int|linux32_sys||faccessat(int fd, netbsd32_charp path, \
+		    int amode); }
 308	UNIMPL	pselect6
 309	UNIMPL	ppoll
 310	UNIMPL	unshare
@@ -517,7 +530,8 @@
 317	UNIMPL	move_pages
 318	UNIMPL	getcpu
 319	UNIMPL	epoll_wait
-320	UNIMPL	utimensat
+320	STD	{ int|linux32_sys||utimensat(int fd, netbsd32_charp path, \
+			    linux32_timespecp_t times, int flag); }
 321	UNIMPL	signalfd
 322	UNIMPL	timerfd_create
 323	UNIMPL	eventfd
@@ -535,3 +549,16 @@
 335	UNIMPL	rt_tgsigqueueinfo
 336	UNIMPL	perf_counter_open
 337	UNIMPL	recvmmsg
+338	UNIMPL	fanotify_init
+339	UNIMPL	fanotify_mark
+340	UNIMPL	prlimit64
+341	UNIMPL	name_to_handle_at
+342	UNIMPL	open_by_handle_at
+343	UNIMPL	clock_adjtime
+344	UNIMPL	syncfs
+345	UNIMPL	sendmmsg
+346	UNIMPL	setns
+347	UNIMPL	process_vm_readv
+348	UNIMPL	process_vm_writev
+349	UNIMPL	kcmp
+350	UNIMPL	finit_module

Index: src/sys/compat/linux32/common/linux32_misc.c
diff -u src/sys/compat/linux32/common/linux32_misc.c:1.22 src/sys/compat/linux32/common/linux32_misc.c:1.23
--- src/sys/compat/linux32/common/linux32_misc.c:1.22	Fri Nov 18 04:08:56 2011
+++ src/sys/compat/linux32/common/linux32_misc.c	Mon Nov 18 01:32:52 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux32_misc.c,v 1.22 2011/11/18 04:08:56 christos Exp $	*/
+/*	$NetBSD: linux32_misc.c,v 1.23 2013/11/18 01:32:52 chs Exp $	*/
 
 /*-
  * Copyright (c) 1995, 1998, 1999 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux32_misc.c,v 1.22 2011/11/18 04:08:56 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux32_misc.c,v 1.23 2013/11/18 01:32:52 chs Exp $");
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -47,13 +47,14 @@ __KERNEL_RCSID(0, "$NetBSD: linux32_misc
 #include <compat/netbsd32/netbsd32.h>
 #include <compat/netbsd32/netbsd32_syscallargs.h>
 
+#include <compat/linux/common/linux_types.h>
+
 #include <compat/linux32/common/linux32_types.h>
 #include <compat/linux32/common/linux32_signal.h>
 #include <compat/linux32/common/linux32_sched.h>
 #include <compat/linux32/linux32_syscallargs.h>
 
 #include <compat/linux/common/linux_ptrace.h>
-#include <compat/linux/common/linux_types.h>
 #include <compat/linux/common/linux_emuldata.h>
 #include <compat/linux/common/linux_signal.h>
 #include <compat/linux/common/linux_misc.h>

Index: src/sys/compat/linux32/common/linux32_signal.c
diff -u src/sys/compat/linux32/common/linux32_signal.c:1.16 src/sys/compat/linux32/common/linux32_signal.c:1.17
--- src/sys/compat/linux32/common/linux32_signal.c:1.16	Thu May 10 19:40:46 2012
+++ src/sys/compat/linux32/common/linux32_signal.c	Mon Nov 18 01:32:52 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux32_signal.c,v 1.16 2012/05/10 19:40:46 christos Exp $ */
+/*	$NetBSD: linux32_signal.c,v 1.17 2013/11/18 01:32:52 chs Exp $ */
 
 /*-
  * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux32_signal.c,v 1.16 2012/05/10 19:40:46 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux32_signal.c,v 1.17 2013/11/18 01:32:52 chs Exp $");
 
 #include <sys/param.h>
 #include <sys/ucred.h>
@@ -44,7 +44,9 @@ __KERNEL_RCSID(0, "$NetBSD: linux32_sign
 
 #include <compat/netbsd32/netbsd32.h>
 
+#include <compat/linux/common/linux_types.h>
 #include <compat/linux/common/linux_signal.h>
+
 #include <compat/linux32/common/linux32_types.h>
 #include <compat/linux32/common/linux32_signal.h>
 #include <compat/linux32/common/linux32_siginfo.h>
Index: src/sys/compat/linux32/common/linux32_stat.c
diff -u src/sys/compat/linux32/common/linux32_stat.c:1.16 src/sys/compat/linux32/common/linux32_stat.c:1.17
--- src/sys/compat/linux32/common/linux32_stat.c:1.16	Thu Jun  4 17:59:30 2009
+++ src/sys/compat/linux32/common/linux32_stat.c	Mon Nov 18 01:32:52 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux32_stat.c,v 1.16 2009/06/04 17:59:30 njoly Exp $ */
+/*	$NetBSD: linux32_stat.c,v 1.17 2013/11/18 01:32:52 chs Exp $ */
 
 /*-
  * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved.
@@ -33,7 +33,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(0, "$NetBSD: linux32_stat.c,v 1.16 2009/06/04 17:59:30 njoly Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux32_stat.c,v 1.17 2013/11/18 01:32:52 chs Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -65,6 +65,7 @@ __KERNEL_RCSID(0, "$NetBSD: linux32_stat
 #include <compat/linux/common/linux_oldolduname.h>
 #include <compat/linux/common/linux_ipc.h>
 #include <compat/linux/common/linux_sem.h>
+#include <compat/linux/common/linux_fcntl.h>
 #include <compat/linux/linux_syscallargs.h>
 
 #include <compat/linux32/common/linux32_types.h>
@@ -249,3 +250,30 @@ linux32_sys_fstat64(struct lwp *l, const
 	bsd_to_linux32_stat64(&st, &st32);
 	return copyout(&st32, SCARG_P32(uap, sp), sizeof(st32));
 }
+
+int
+linux32_sys_fstatat64(struct lwp *l, const struct linux32_sys_fstatat64_args *uap, register_t *retval)
+{
+	/* {
+		syscallarg(int) fd;
+		syscallarg(netbsd32_charp) path;
+		syscallarg(linux32_stat64p) sp;
+		syscallarg(int) flag;
+	} */
+	int error, nd_flag;
+	struct stat st;
+	struct linux32_stat64 st32;
+
+	if (SCARG(uap, flag) & LINUX_AT_SYMLINK_NOFOLLOW)
+		nd_flag = NOFOLLOW;
+	else
+		nd_flag = FOLLOW;
+
+	error = do_sys_statat(l, SCARG(uap, fd), SCARG_P32(uap, path), nd_flag, &st);
+	if (error != 0)
+		return error;
+
+	bsd_to_linux32_stat64(&st, &st32);
+
+	return copyout(&st32, SCARG_P32(uap, sp), sizeof st32);
+}

Reply via email to