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), <s, sizeof(lts));
- if (error != 0)
- return error;
- linux_to_native_timespec(&ts[0], <s[0]);
- linux_to_native_timespec(&ts[1], <s[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), <v, sizeof(ltv))))
+ error = copyin(SCARG(uap, times), <s, 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], <s[0]);
+ linux_to_native_timespec(&ts[1], <s[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);
+}