]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Y2038: add function __futimes64
authorAlbert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Thu, 7 Sep 2017 22:41:43 +0000 (00:41 +0200)
committerAlbert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Wed, 24 Oct 2018 10:53:27 +0000 (12:53 +0200)
misc/futimes.c
sysdeps/unix/sysv/linux/futimes.c
time/Versions

index 3ffa40b0b11f74c76022cb7b673063e1d082fa1f..c8756a01d258bf1e41e9e73a8c3804d461e65cba 100644 (file)
@@ -30,3 +30,12 @@ __futimes (int fd, const struct timeval tvp[2])
 weak_alias (__futimes, futimes)
 
 stub_warning (futimes)
+
+int
+__futimes64 (int fd, const struct __timeval64 tvp[2])
+{
+  __set_errno (ENOSYS);
+  return -1;
+}
+
+stub_warning (__futimes64)
index 9e6267cda78ffa19c69f1c2f5cb9ed78497a0d8a..c3d76780da4590f783437bc9a957cdaf7ac461ac 100644 (file)
@@ -24,6 +24,7 @@
 #include <sys/time.h>
 #include <_itoa.h>
 #include <fcntl.h>
+#include <y2038-support.h>
 
 
 /* Change the access time of the file associated with FD to TVP[0] and
@@ -49,3 +50,61 @@ __futimes (int fd, const struct timeval tvp[2])
   return INLINE_SYSCALL (utimensat, 4, fd, NULL, tvp ? &ts : NULL, 0);
 }
 weak_alias (__futimes, futimes)
+
+/* 64-bit time version */
+
+int
+__futimes64 (int fd, const struct __timeval64 tvp[2])
+{
+  struct timespec ts32[2], *ts32p = NULL;
+/* Only try and use this syscall if defined by kernel */
+#ifdef __NR_utimensat_time64
+  /* The utimensat system call expects timespec not timeval.  */
+  struct __timespec64 ts64[2], *ts64p = NULL;
+  int result;
+#endif
+
+/* Only try and use this syscall if defined by kernel */
+#ifdef __NR_utimensat_time64
+  if (__y2038_linux_support > 0)
+    {
+      if (tvp != NULL)
+        {
+          if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000
+              || tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000)
+           return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
+        
+          ts64[0].tv_sec = tvp[0].tv_sec;
+          ts64[0].tv_nsec = tvp[0].tv_usec * 1000;
+          ts64[0].tv_pad = 0;
+          ts64[1].tv_sec = tvp[1].tv_sec;
+          ts64[1].tv_nsec = tvp[1].tv_usec * 1000;
+          ts64[1].tv_pad = 0;
+          ts64p = ts64;
+        }
+    
+      result = INLINE_SYSCALL (utimensat_time64, 4, fd, NULL, ts64p, 0);
+      if (result == 0 || errno != ENOSYS)
+        return result;
+      __y2038_linux_support = -1;
+    }
+#endif
+
+  if (tvp != NULL)
+    {
+      if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000
+          || tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000)
+        return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
+    
+      if (tvp[0].tv_sec > INT_MAX || tvp[1].tv_sec > INT_MAX)
+        return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
+    
+      ts32[0].tv_sec = tvp[0].tv_sec;
+      ts32[0].tv_nsec = tvp[0].tv_usec * 1000;
+      ts32[1].tv_sec = tvp[1].tv_sec;
+      ts32[1].tv_nsec = tvp[1].tv_usec * 1000;
+      ts32p = ts32;
+    }
+
+  return INLINE_SYSCALL (utimensat, 4, fd, NULL, ts32p, 0);
+}
index 8e5f02189b820aabc5c45295b176070832fc2187..0a55284d11ca75153714dfe9bac9dc8c24364684 100644 (file)
@@ -78,5 +78,6 @@ libc {
     __utimensat_time64;
     __futimens64;
     __sigtimedwait_time64;
+    __futimes64;
   }
 }