diff options
author | Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr> | 2017-09-08 00:41:39 +0200 |
---|---|---|
committer | Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr> | 2018-10-24 12:53:27 +0200 |
commit | 50673e789f5528e0ea422e39d60aadb869e3dc1f (patch) | |
tree | b01a657453482503dfe872fdcd794c882a228fe4 /sysdeps/unix/sysv/linux/futimens.c | |
parent | 440d708a8ef153c87cf3534ab9a8a6973321e546 (diff) | |
download | glibc-50673e789f5528e0ea422e39d60aadb869e3dc1f.tar glibc-50673e789f5528e0ea422e39d60aadb869e3dc1f.tar.gz glibc-50673e789f5528e0ea422e39d60aadb869e3dc1f.tar.bz2 glibc-50673e789f5528e0ea422e39d60aadb869e3dc1f.zip |
Y2038: add function __futimens64
Diffstat (limited to 'sysdeps/unix/sysv/linux/futimens.c')
-rw-r--r-- | sysdeps/unix/sysv/linux/futimens.c | 49 |
1 files changed, 48 insertions, 1 deletions
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); +} |