[RFC,13/52] Y2038: add function __utimensat64

Message ID 20170907224219.12483-14-albert.aribaud@3adev.fr
State New
Headers show
Series
  • Make GLIBC Y2038-proof
Related show

Commit Message

Albert ARIBAUD Sept. 7, 2017, 10:41 p.m.
Signed-off-by: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
---
 io/utimensat.c                       |  9 +++++++++
 sysdeps/unix/sysv/linux/arm/Versions |  1 +
 sysdeps/unix/sysv/linux/utimensat.c  | 36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 46 insertions(+)

Patch

diff --git a/io/utimensat.c b/io/utimensat.c
index f45eb73b93..6b9cf43d4b 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
+__utimensat64 (int fd, const char *file, const struct __timespec64 tsp[2],
+	   int flags)
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (__utimensat64)
diff --git a/sysdeps/unix/sysv/linux/arm/Versions b/sysdeps/unix/sysv/linux/arm/Versions
index 08dfae2b61..2620d81fdc 100644
--- a/sysdeps/unix/sysv/linux/arm/Versions
+++ b/sysdeps/unix/sysv/linux/arm/Versions
@@ -34,5 +34,6 @@  libc {
     __clock_getres64;
     __clock_nanosleep64;
     __futimens64;
+    __utimensat64;
   }
 }
diff --git a/sysdeps/unix/sysv/linux/utimensat.c b/sysdeps/unix/sysv/linux/utimensat.c
index 87f1ef04e0..baa718686e 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 <stdio.h>
 
 
 /* Change the access time of FILE to TSP[0] and
@@ -34,3 +35,38 @@  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 */
+
+extern int __y2038_linux_support;
+
+int
+__utimensat64 (int fd, const char *file, const struct __timespec64 tsp[2],
+	   int flags)
+{
+  struct __timespec64 ts64[2];
+  struct timespec ts32[2];
+
+  if (file == NULL)
+    return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
+
+  if (!tsp)
+    return INLINE_SYSCALL (utimensat64, 4, fd, file, NULL, flags);
+
+  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;
+      return INLINE_SYSCALL (utimensat64, 4, fd, file, &ts64, flags);
+    }
+
+  ts32[0].tv_sec = tsp[0].tv_sec;
+  ts32[0].tv_nsec = tsp[0].tv_nsec;
+  ts32[1].tv_sec = tsp[1].tv_sec;
+  ts32[1].tv_nsec = tsp[1].tv_nsec;
+  return INLINE_SYSCALL (utimensat, 4, fd, file, &ts32, flags);
+}