]> Savannah Git Hosting - gnulib.git/commitdiff
readutmp: Get the boot time with higher precision.
authorBruno Haible <bruno@clisp.org>
Tue, 8 Aug 2023 19:28:46 +0000 (21:28 +0200)
committerBruno Haible <bruno@clisp.org>
Tue, 8 Aug 2023 19:28:46 +0000 (21:28 +0200)
Suggested by Thorsten Kukuk <kukuk@suse.com> in
<https://github.com/thkukuk/utmpx/blob/main/utmp-to-logind.md#determine-boot-time>.

* lib/readutmp.c (get_boot_time_uncached): Try clock_gettime first.

ChangeLog
lib/readutmp.c

index 1697d8a3b940b4029fd610a8b2f3b52dd52dda94..62e281fa9783136b1740b957761108f047224e6b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2023-08-08  Bruno Haible  <bruno@clisp.org>
+
+       readutmp: Get the boot time with higher precision.
+       Suggested by Thorsten Kukuk <kukuk@suse.com> in
+       <https://github.com/thkukuk/utmpx/blob/main/utmp-to-logind.md#determine-boot-time>.
+       * lib/readutmp.c (get_boot_time_uncached): Try clock_gettime first.
+
 2023-08-08  Bruno Haible  <bruno@clisp.org>
 
        readutmp: Add comment about multithread-safety.
index 7ef5bfe84c4c85420e86f9a7d6b2993951828ae3..f7e43eb4a6ce351e6741c48690ddfb69fe3e5574 100644 (file)
@@ -284,6 +284,31 @@ finish_utmp (struct utmp_alloc a)
 static struct timespec
 get_boot_time_uncached (void)
 {
+  /* The clock_gettime facility returns the uptime with a resolution of 1 µsec.
+     It is available with glibc >= 2.14.  In glibc < 2.17 it required linking
+     with librt.  */
+#  if __GLIBC__ + (__GLIBC_MINOR__ >= 17) > 2
+  struct timespec up;
+  if (clock_gettime (CLOCK_BOOTTIME, &up) >= 0)
+    {
+      struct timespec result;
+      /* equivalent to:
+      if (clock_gettime (CLOCK_REALTIME, &result) >= 0)
+      */
+      if (timespec_get (&result, TIME_UTC) >= 0)
+        {
+          if (result.tv_nsec < up.tv_nsec)
+            {
+              result.tv_nsec += 1000000000;
+              result.tv_sec -= 1;
+            }
+          result.tv_sec -= up.tv_sec;
+          result.tv_nsec -= up.tv_nsec;
+          return result;
+        }
+    }
+#  endif
+
   /* /proc/uptime contains the uptime with a resolution of 0.01 sec.  */
   FILE *fp = fopen ("/proc/uptime", "re");
   if (fp != NULL)