diff options
-rw-r--r-- | io/futimens.c | 8 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/futimens.c | 49 | ||||
-rw-r--r-- | time/Versions | 1 |
3 files changed, 57 insertions, 1 deletions
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..5de651d2cd 100644 --- a/sysdeps/unix/sysv/linux/futimens.c +++ b/sysdeps/unix/sysv/linux/futimens.c @@ -21,7 +21,7 @@ #include <string.h> #include <time.h> #include <sysdep.h> - +#include <y2038-support.h> /* Change the access time of the file associated with FD to TSP[0] and the modification time of FILE to TSP[1]. @@ -36,3 +36,50 @@ 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 */ + +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_utimesat_time64 + 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_utimesat_time64 + if (__y2038_linux_support > 0) + { + 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 (utimensat_time64, 4, fd, NULL, &ts64[0], 0); + if (res == 0 || errno != ENOSYS) + return res; + __y2038_linux_support = -1; + } +#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 c5f63364c0..5614729fc5 100644 --- a/time/Versions +++ b/time/Versions @@ -76,5 +76,6 @@ libc { __clock_nanosleep64; __timespec_get64; __utimensat_time64; + __futimens64; } } |