Date: Fri, 30 Jan 2015 00:06:26 +0100 From: Jilles Tjoelker <jilles@stack.nl> To: Andrew Wilcox <AWilcox@Wilcox-Tech.com> Cc: freebsd-arch@FreeBSD.org Subject: Re: Current status of utimensat(2) Message-ID: <20150129230625.GA26181@stack.nl> In-Reply-To: <005701d03b53$92796ce0$b76c46a0$@Wilcox-Tech.com> References: <005701d03b53$92796ce0$b76c46a0$@Wilcox-Tech.com>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
On Wed, Jan 28, 2015 at 05:38:50PM -0600, Andrew Wilcox wrote:
> I am wondering about the current status of the utimensat(2) and
> futimens(2) patch set. I saw some posts from early 2013 but nothing
> more recent. In addition to improving POSIX 2008 compliance, this
> will additionally enable me to continue my work on the Linuxulator.
> As it stands, most Gentoo and Ubuntu binaries do not work in the
> Linuxulator because of the missing utimensat syscall.
> Is anyone currently working on this? I'd be happy to help out.
I committed utimensat/futimens to head. I also made a start at
Linuxulator utimensat, see attached patch. Please complete it and test
it.
--
Jilles Tjoelker
[-- Attachment #2 --]
commit 579d4ad12989f5ab88983d461156d16bb5bcdec1
Author: Jilles Tjoelker <jilles@stack.nl>
Date: Sun Jan 25 01:09:37 2015 +0100
Add Linux utimensat() syscall.
Conflicts:
sys/compat/linux/linux_file.h
diff --git a/sys/compat/linux/linux_file.h b/sys/compat/linux/linux_file.h
index 2d3106f..58e80f1 100644
--- a/sys/compat/linux/linux_file.h
+++ b/sys/compat/linux/linux_file.h
@@ -54,4 +54,7 @@
#define LINUX_MS_NOEXEC 0x0008
#define LINUX_MS_REMOUNT 0x0020
+#define LINUX_UTIME_NOW 0x3fffffff
+#define LINUX_UTIME_OMIT 0x3ffffffe
+
#endif /* !_LINUX_FILE_H_ */
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 93dd80d..262ada9 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -851,6 +851,66 @@ linux_futimesat(struct thread *td, struct linux_futimesat_args *args)
#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
int
+linux_utimensat(struct thread *td, struct linux_utimensat_args *args)
+{
+ struct l_timespec lts[2];
+ struct timespec ts[2], *tsp = NULL;
+ char *fname;
+ int error, fd, flag;
+
+ if (args->utimes != NULL) {
+ if ((error = copyin(args->utimes, lts, sizeof lts)))
+ return (error);
+ ts[0].tv_sec = lts[0].tv_sec;
+ if (lts[0].tv_nsec >= 0 && lts[0].tv_nsec < 1000000000)
+ ts[0].tv_nsec = lts[0].tv_nsec;
+ else if (lts[0].tv_nsec == LINUX_UTIME_NOW)
+ ts[0].tv_nsec = UTIME_NOW;
+ else if (lts[0].tv_nsec == LINUX_UTIME_OMIT)
+ ts[0].tv_nsec = UTIME_OMIT;
+ else
+ return (EINVAL);
+ ts[1].tv_sec = lts[1].tv_sec;
+ if (lts[1].tv_nsec >= 0 && lts[1].tv_nsec < 1000000000)
+ ts[1].tv_nsec = lts[1].tv_nsec;
+ else if (lts[1].tv_nsec == LINUX_UTIME_NOW)
+ ts[1].tv_nsec = UTIME_NOW;
+ else if (lts[1].tv_nsec == LINUX_UTIME_OMIT)
+ ts[1].tv_nsec = UTIME_OMIT;
+ else
+ return (EINVAL);
+ tsp = ts;
+ }
+
+ if (args->pathname == NULL) {
+ if (args->flag != 0)
+ return (EINVAL);
+ fname = NULL;
+ flag = 0;
+ } else {
+ if (args->flag & ~LINUX_AT_SYMLINK_NOFOLLOW)
+ return (EINVAL);
+ fd = (args->fd == LINUX_AT_FDCWD) ? AT_FDCWD : args->fd;
+ LCONVPATHEXIST_AT(td, args->pathname, &fname, fd);
+ flag = args->flag & LINUX_AT_SYMLINK_NOFOLLOW ?
+ AT_SYMLINK_NOFOLLOW : 0;
+ }
+
+#ifdef DEBUG
+ if (ldebug(utimensat))
+ printf(ARGS(utimensat, "%s, *"), fname);
+#endif
+
+ if (fname == NULL)
+ error = kern_futimens(td, fd, tsp, UIO_SYSSPACE);
+ else
+ error = kern_utimensat(td, fd, fname, UIO_SYSSPACE, tsp,
+ UIO_SYSSPACE, flag);
+ LFREEPATH(fname);
+ return (error);
+}
+
+int
linux_common_wait(struct thread *td, int pid, int *status,
int options, struct rusage *ru)
{
diff --git a/sys/i386/linux/linux_dummy.c b/sys/i386/linux/linux_dummy.c
index 85d40f0..4a63994 100644
--- a/sys/i386/linux/linux_dummy.c
+++ b/sys/i386/linux/linux_dummy.c
@@ -107,7 +107,6 @@ DUMMY(move_pages);
DUMMY(getcpu);
DUMMY(epoll_pwait);
/* linux 2.6.22: */
-DUMMY(utimensat);
DUMMY(signalfd);
DUMMY(timerfd_create);
DUMMY(eventfd);
diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master
index 5b4f3a6..516980a 100644
--- a/sys/i386/linux/syscalls.master
+++ b/sys/i386/linux/syscalls.master
@@ -532,7 +532,7 @@
318 AUE_NULL STD { int linux_getcpu(void); }
319 AUE_NULL STD { int linux_epoll_pwait(void); }
; linux 2.6.22:
-320 AUE_NULL STD { int linux_utimensat(void); }
+320 AUE_FUTIMESAT STD { int linux_utimensat(l_int fd, const char *pathname, const struct l_timespec *utimes, l_int flag); }
321 AUE_NULL STD { int linux_signalfd(void); }
322 AUE_NULL STD { int linux_timerfd_create(void); }
323 AUE_NULL STD { int linux_eventfd(void); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20150129230625.GA26181>
