From a39e5b2c41b91cfd198f3070002da98ba1b6595e Mon Sep 17 00:00:00 2001 From: "Albert ARIBAUD (3ADEV)" Date: Fri, 8 Sep 2017 00:41:39 +0200 Subject: Y2038: add function __futimens64 --- io/futimens.c | 8 +++++++ sysdeps/unix/sysv/linux/futimens.c | 48 ++++++++++++++++++++++++++++++++++++++ time/Versions | 1 + 3 files changed, 57 insertions(+) diff --git a/io/futimens.c b/io/futimens.c index fb170ffc3c..2e9648a16e 100644 --- a/io/futimens.c +++ b/io/futimens.c @@ -32,3 +32,11 @@ futimens (int fd, const struct timespec tsp[2]) return -1; } stub_warning (futimens) + +int +__futimens64 (int fd, const struct __timespec64 tsp[2]) +{ + __set_errno (ENOSYS); + return -1; +} +stub_warning (__futimens64) diff --git a/sysdeps/unix/sysv/linux/futimens.c b/sysdeps/unix/sysv/linux/futimens.c index bc7fe54331..fb338b92ea 100644 --- a/sysdeps/unix/sysv/linux/futimens.c +++ b/sysdeps/unix/sysv/linux/futimens.c @@ -36,3 +36,51 @@ futimens (int fd, const struct timespec tsp[2]) /* Avoid implicit array coercion in syscall macros. */ return INLINE_SYSCALL (utimensat, 4, fd, NULL, &tsp[0], 0); } + +/* 64-bit time version */ + +extern int __y2038_linux_support; + +int +__futimens64 (int fd, const struct __timespec64 tsp[2]) +{ + struct timespec ts32[2]; +/* Only try and use this syscall if defined by kernel */ +#ifdef __NR_utimesat64 + struct __timespec64 ts64[2]; + int res; +#endif + + if (fd < 0) + return INLINE_SYSCALL_ERROR_RETURN_VALUE (EBADF); + +/* Only try and use this syscall if defined by kernel */ +#ifdef __NR_utimesat64 + if (__y2038_linux_support) + { + ts64[0].tv_sec = tsp[0].tv_sec; + ts64[0].tv_nsec = tsp[0].tv_nsec; + ts64[0].tv_pad = 0; + ts64[1].tv_sec = tsp[1].tv_sec; + ts64[1].tv_nsec = tsp[1].tv_nsec; + ts64[1].tv_pad = 0; + res = INLINE_SYSCALL (utimensat64, 4, fd, NULL, &ts64[0], 0); + if (res == 0 || errno != ENOSYS) + return res; + } +#endif + + if (! timespec64_to_timespec(&tsp[0], &ts32[0])) + { + __set_errno(EOVERFLOW); + return -1; + } + + if (! timespec64_to_timespec(&tsp[1], &ts32[1])) + { + __set_errno(EOVERFLOW); + return -1; + } + + return INLINE_SYSCALL (utimensat, 4, fd, NULL, &ts32[0], 0); +} diff --git a/time/Versions b/time/Versions index 668c134f12..6105da5cb9 100644 --- a/time/Versions +++ b/time/Versions @@ -79,5 +79,6 @@ libc { __clock_getres64; __clock_nanosleep64; __timespec_get64; + __futimens64; } } -- cgit v1.2.1