aboutsummaryrefslogtreecommitdiff
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
parente4625075c84988c2a196b381909e676ccf01338f (diff)
downloadglibc-440d708a8ef153c87cf3534ab9a8a6973321e546.zip
glibc-440d708a8ef153c87cf3534ab9a8a6973321e546.tar.gz
glibc-440d708a8ef153c87cf3534ab9a8a6973321e546.tar.bz2
Y2038: add function __utimensat_time64
-rw-r--r--io/utimensat.c9
-rw-r--r--sysdeps/unix/sysv/linux/utimensat.c58
-rw-r--r--time/Versions1
3 files changed, 68 insertions, 0 deletions
diff --git a/io/utimensat.c b/io/utimensat.c
index 6b67a52..c535930 100644
--- a/io/utimensat.c
+++ b/io/utimensat.c
@@ -30,3 +30,12 @@ utimensat (int fd, const char *file, const struct timespec tsp[2],
return -1;
}
stub_warning (utimensat)
+
+int
+__utimensat_time64 (int fd, const char *file, const struct __timespec64 tsp[2],
+ int flags)
+{
+ __set_errno (ENOSYS);
+ return -1;
+}
+stub_warning (__utimensat_time64)
diff --git a/sysdeps/unix/sysv/linux/utimensat.c b/sysdeps/unix/sysv/linux/utimensat.c
index 108d3bc..a0d1f5d 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);
+}
diff --git a/time/Versions b/time/Versions
index 1e4d81b..c5f6336 100644
--- a/time/Versions
+++ b/time/Versions
@@ -75,5 +75,6 @@ libc {
__clock_getres_time64;
__clock_nanosleep64;
__timespec_get64;
+ __utimensat_time64;
}
}