bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: bug#64937: "who" reports funny dates


From: Bruno Haible
Subject: Re: bug#64937: "who" reports funny dates
Date: Tue, 08 Aug 2023 21:32:02 +0200

Thorsten Kukuk wrote:
> > What API do you suggest we use instead?
> 
> For me clock_gettime works very well:
> https://github.com/thkukuk/utmpx/blob/main/utmp-to-logind.md#determine-boot-time

Indeed, this provides the boot time with a resolution of 1 µsec. Whereas the
/proc/uptime approach only has a resolution of 10000 µsec. Thanks for the
suggestion.


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.

diff --git a/lib/readutmp.c b/lib/readutmp.c
index 7ef5bfe84c..f7e43eb4a6 100644
--- a/lib/readutmp.c
+++ b/lib/readutmp.c
@@ -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)






reply via email to

[Prev in Thread] Current Thread [Next in Thread]