diff options
Diffstat (limited to 'sys/compat/linux/common')
| -rw-r--r-- | sys/compat/linux/common/linux_fcntl.h | 11 | ||||
| -rw-r--r-- | sys/compat/linux/common/linux_file.c | 21 | ||||
| -rw-r--r-- | sys/compat/linux/common/linux_misc.c | 47 |
3 files changed, 74 insertions, 5 deletions
diff --git a/sys/compat/linux/common/linux_fcntl.h b/sys/compat/linux/common/linux_fcntl.h index cfaa3add61d..ada0720e330 100644 --- a/sys/compat/linux/common/linux_fcntl.h +++ b/sys/compat/linux/common/linux_fcntl.h @@ -1,4 +1,4 @@ -/* $NetBSD: linux_fcntl.h,v 1.14 2008/04/28 20:23:43 martin Exp $ */ +/* $NetBSD: linux_fcntl.h,v 1.15 2013/09/24 13:27:50 njoly Exp $ */ /*- * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc. @@ -43,6 +43,15 @@ #define LINUX_O_RDWR 0x0002 #define LINUX_O_ACCMODE 0x0003 +#define LINUX_AT_FDCWD -100 +#define LINUX_AT_SYMLINK_NOFOLLOW 0x0100 +#define LINUX_AT_REMOVEDIR 0x0200 +#define LINUX_AT_SYMLINK_FOLLOW 0x0400 +#define LINUX_AT_NO_AUTOMOUNT 0x0800 +#define LINUX_AT_EMPTY_PATH 0x1000 + +int linux_to_bsd_atflags(int); + struct linux_flock { short l_type; short l_whence; diff --git a/sys/compat/linux/common/linux_file.c b/sys/compat/linux/common/linux_file.c index fd5d8aacc57..8e7a653dfcd 100644 --- a/sys/compat/linux/common/linux_file.c +++ b/sys/compat/linux/common/linux_file.c @@ -1,4 +1,4 @@ -/* $NetBSD: linux_file.c,v 1.104 2011/10/14 09:23:28 hannken Exp $ */ +/* $NetBSD: linux_file.c,v 1.105 2013/09/24 13:27:50 njoly 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.104 2011/10/14 09:23:28 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux_file.c,v 1.105 2013/09/24 13:27:50 njoly Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -643,6 +643,23 @@ linux_sys_dup3(struct lwp *l, const struct linux_sys_dup3_args *uap, return 0; } + +int +linux_to_bsd_atflags(int lflags) +{ + int bflags = 0; + + if (lflags & LINUX_AT_SYMLINK_NOFOLLOW) + bflags |= AT_SYMLINK_NOFOLLOW; + if (lflags & LINUX_AT_REMOVEDIR) + bflags |= AT_REMOVEDIR; + if (lflags & LINUX_AT_SYMLINK_FOLLOW) + bflags |= AT_SYMLINK_FOLLOW; + + return bflags; +} + + #define LINUX_NOT_SUPPORTED(fun) \ int \ fun(struct lwp *l, const struct fun##_args *uap, register_t *retval) \ diff --git a/sys/compat/linux/common/linux_misc.c b/sys/compat/linux/common/linux_misc.c index 83f79c02575..d0344d54520 100644 --- a/sys/compat/linux/common/linux_misc.c +++ b/sys/compat/linux/common/linux_misc.c @@ -1,4 +1,4 @@ -/* $NetBSD: linux_misc.c,v 1.225 2013/09/15 12:58:34 njoly Exp $ */ +/* $NetBSD: linux_misc.c,v 1.226 2013/09/24 13:27:50 njoly 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.225 2013/09/15 12:58:34 njoly Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux_misc.c,v 1.226 2013/09/24 13:27:50 njoly Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -1409,6 +1409,49 @@ linux_sys_utimes(struct lwp *l, const struct linux_sys_utimes_args *uap, registe tptr, UIO_SYSSPACE); } +int +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_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; + + 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) { + file_t *fp; + + /* fd_getvnode() will use the descriptor for us */ + if ((error = fd_getvnode(SCARG(uap, 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)); + return error; + } + + return do_sys_utimensat(l, SCARG(uap, fd), NULL, + SCARG(uap, 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) |
