]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libuuid: Add uuid_time64 for 64bit time_t on 32bit
authorThorsten Kukuk <kukuk@suse.com>
Thu, 30 Nov 2023 15:28:53 +0000 (16:28 +0100)
committerThorsten Kukuk <kukuk@node147.libvirt.thkukuk.de>
Fri, 8 Dec 2023 13:41:25 +0000 (14:41 +0100)
Signed-off-by: Thorsten Kukuk <kukuk@suse.com>
libuuid/src/libuuid.sym
libuuid/src/uuid.h
libuuid/src/uuid_time.c

index 96372a857f55eb8864a80278bb1db46a182a864d..0f67ede0d5228f361ca3d7133b6c8a3dee4be54d 100644 (file)
@@ -52,6 +52,15 @@ global:
        uuid_parse_range;
 } UUID_2.31;
 
+/*
+ * version(s) since util-linux.2.40
+ */
+UUID_2.40 {
+global:
+        uuid_time64; /* only on 32bit architectures with 64bit time_t */
+} UUID_2.36;
+
+
 
 /*
  * __uuid_* this is not part of the official API, this is
index e791abf67874f5970b3d12485b3eed42de065eca..2e3642cd63731587dead817a4037dd08c4a15b32 100644 (file)
@@ -109,6 +109,9 @@ extern void uuid_unparse_lower(const uuid_t uu, char *out);
 extern void uuid_unparse_upper(const uuid_t uu, char *out);
 
 /* uuid_time.c */
+#if defined(__USE_TIME_BITS64) && defined(__GLIBC__)
+# define uuid_time uuid_time64
+#endif
 extern time_t uuid_time(const uuid_t uu, struct timeval *ret_tv);
 extern int uuid_type(const uuid_t uu);
 extern int uuid_variant(const uuid_t uu);
index 6f07d51035a263dbf6a302d35e845bcbddf1085e..9b415b3ee73a20788d372673f5425f970b6ac879 100644 (file)
@@ -40,6 +40,7 @@
 #define UUID MYUUID
 #endif
 
+#include <errno.h>
 #include <stdio.h>
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 
 #include "uuidP.h"
 
-time_t uuid_time(const uuid_t uu, struct timeval *ret_tv)
+#undef uuid_time
+
+/* prototype to make compiler happy */
+time_t __uuid_time(const uuid_t uu, struct timeval *ret_tv);
+
+
+/* this function could be 32bit time_t and 32bit timeval or 64bit,
+   depending on compiler flags and architecture. */
+time_t __uuid_time(const uuid_t uu, struct timeval *ret_tv)
 {
        struct timeval          tv;
        struct uuid             uuid;
@@ -74,6 +83,54 @@ time_t uuid_time(const uuid_t uu, struct timeval *ret_tv)
 
        return tv.tv_sec;
 }
+#if defined(__USE_TIME_BITS64) && defined(__GLIBC__)
+extern time_t uuid_time64(const uuid_t uu, struct timeval *ret_tv) __attribute__((weak, alias("__uuid_time")));
+#else
+extern time_t uuid_time(const uuid_t uu, struct timeval *ret_tv) __attribute__((weak, alias("__uuid_time")));
+#endif
+     
+#if defined(__USE_TIME_BITS64) && defined(__GLIBC__)
+struct timeval32
+{
+       int32_t tv_sec;
+       int32_t tv_usec;
+};
+
+/* prototype to make compiler happy */
+int32_t __uuid_time32(const uuid_t uu, struct timeval32 *ret_tv);
+
+/* Check whether time fits in 32bit time_t.  */
+static inline int
+in_time32_t_range(time_t t)
+{
+       int32_t         s;
+       s = t;
+
+       return s == t;
+}
+
+int32_t __uuid_time32(const uuid_t uu, struct timeval32 *ret_tv)
+{
+       struct timeval          tv;
+       time_t ret_time = __uuid_time(uu, &tv);
+
+       if (! in_time32_t_range(ret_time)) {
+               ret_tv->tv_sec = -1;
+               ret_tv->tv_usec = -1;
+               errno = EOVERFLOW;
+               return -1;
+       }
+
+       if (ret_tv) {
+               ret_tv->tv_sec = tv.tv_sec;
+               ret_tv->tv_usec = tv.tv_usec;
+       }
+
+       return tv.tv_sec;
+}
+extern int32_t uuid_time(const uuid_t uu, struct timeval32 *ret_tv) __attribute__((weak, alias("__uuid_time32")));
+#endif
 
 int uuid_type(const uuid_t uu)
 {