aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/unix/sysv/linux
diff options
context:
space:
mode:
authorAlbert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>2017-09-08 00:41:40 +0200
committerAlbert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>2018-10-24 12:53:27 +0200
commit440d708a8ef153c87cf3534ab9a8a6973321e546 (patch)
treed4f11affd5e97fba2d281216282262cfbaaea0f9 /sysdeps/unix/sysv/linux
parente4625075c84988c2a196b381909e676ccf01338f (diff)
downloadglibc-440d708a8ef153c87cf3534ab9a8a6973321e546.tar
glibc-440d708a8ef153c87cf3534ab9a8a6973321e546.tar.gz
glibc-440d708a8ef153c87cf3534ab9a8a6973321e546.tar.bz2
glibc-440d708a8ef153c87cf3534ab9a8a6973321e546.zip
Y2038: add function __utimensat_time64
Diffstat (limited to 'sysdeps/unix/sysv/linux')
-rw-r--r--sysdeps/unix/sysv/linux/utimensat.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/utimensat.c b/sysdeps/unix/sysv/linux/utimensat.c
index 108d3bc55b..a0d1f5d876 100644
--- a/sysdeps/unix/sysv/linux/utimensat.c
+++ b/sysdeps/unix/sysv/linux/utimensat.c
@@ -19,6 +19,7 @@
#include <errno.h>
#include <sys/stat.h>
#include <sysdep.h>
+#include <y2038-support.h>
/* Change the access time of FILE to TSP[0] and
@@ -34,3 +35,60 @@ utimensat (int fd, const char *file, const struct timespec tsp[2],
/* Avoid implicit array coercion in syscall macros. */
return INLINE_SYSCALL (utimensat, 4, fd, file, &tsp[0], flags);
}
+
+/* 64-bit time version */
+
+int
+__utimensat_time64 (int fd, const char *file, const struct __timespec64 tsp[2],
+ int flags)
+{
+ struct timespec ts32[2], *ts32p = NULL;
+/* Only try and use this syscall if defined by kernel */
+#ifdef __NR_utimensat_time64
+ struct __timespec64 ts64[2], *ts64p = NULL;
+ int res;
+#endif
+
+ if (file == NULL)
+ return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
+
+/* Only try and use this syscall if defined by kernel */
+#ifdef __NR_utimensat_time64
+ if (__y2038_linux_support > 0)
+ {
+ if (tsp)
+ {
+ 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;
+ ts64p = ts64;
+ }
+
+ res = INLINE_SYSCALL (utimensat_time64, 4, fd, file, ts64p, flags);
+ if (res == 0 || errno != ENOSYS)
+ return res;
+ __y2038_linux_support = -1;
+ }
+#endif
+
+ if (tsp)
+ {
+ 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;
+ }
+ ts32p = ts32;
+ }
+
+ return INLINE_SYSCALL (utimensat, 4, fd, file, ts32p, flags);
+}