Originally I wrote the readutmp.c code in such a way that, on Linux, we use the
fallback code for the boot time only if --enable-systemd is specified.

But the same fallback code is also useful on older systems or without systemd,
namely for processes which run in partial isolation from the file system (such
as Docker containers). In such situations, we must expect that accessing
/var/run/utmp fails.

This patch enables it in this situation.


2023-08-12  Bruno Haible  <br...@clisp.org>

        readutmp: On Linux, don't fail if /var/run/utmp is not accessible.
        * lib/boot-time-aux.h (get_linux_boot_time_final_fallback): Don't test
        NEED_BOOT_TIME_FINAL_FALLBACK.
        * lib/boot-time.c (NEED_BOOT_TIME_FINAL_FALLBACK): Remove macro.
        * lib/readutmp.c (NEED_BOOT_TIME_FINAL_FALLBACK): Remove macro.
        (read_utmp_from_file): As a fallback on Linux, invoke
        get_linux_boot_time_final_fallback.
        (get_boot_time_uncached): Don't do it here.
        * m4/readutmp.m4 (gl_READUTMP): Add $CLOCK_TIME_LIB to READUTMP_LIB.

diff --git a/lib/boot-time-aux.h b/lib/boot-time-aux.h
index 8006b72134..e9f58e9d7e 100644
--- a/lib/boot-time-aux.h
+++ b/lib/boot-time-aux.h
@@ -101,8 +101,6 @@ get_linux_boot_time_fallback (struct timespec *p_boot_time)
   return -1;
 }
 
-# if NEED_BOOT_TIME_FINAL_FALLBACK
-
 /* The following approach is only usable as a fallback, because it is of
    the form
      boot_time = (time now) - (kernel's ktime_get_boottime[_ts64] ())
@@ -136,8 +134,6 @@ get_linux_boot_time_final_fallback (struct timespec 
*p_boot_time)
   return -1;
 }
 
-# endif
-
 #endif
 
 #if defined __ANDROID__
diff --git a/lib/boot-time.c b/lib/boot-time.c
index 53bd8b148b..d813bfa582 100644
--- a/lib/boot-time.c
+++ b/lib/boot-time.c
@@ -51,7 +51,6 @@
 #include "unlocked-io.h"
 
 /* Some helper functions.  */
-#define NEED_BOOT_TIME_FINAL_FALLBACK 1
 #include "boot-time-aux.h"
 
 /* The following macros describe the 'struct UTMP_STRUCT_NAME',
diff --git a/lib/readutmp.c b/lib/readutmp.c
index d0c6303466..ef9f0aff43 100644
--- a/lib/readutmp.c
+++ b/lib/readutmp.c
@@ -58,7 +58,6 @@
 #include "unlocked-io.h"
 
 /* Some helper functions.  */
-#define NEED_BOOT_TIME_FINAL_FALLBACK READUTMP_USE_SYSTEMD
 #include "boot-time-aux.h"
 
 /* The following macros describe the 'struct UTMP_STRUCT_NAME',
@@ -587,6 +586,23 @@ read_utmp_from_file (char const *file, idx_t *n_entries, 
STRUCT_UTMP **utmp_buf,
 
 #  endif
 
+#  if defined __linux__ && !defined __ANDROID__
+  if ((options & (READ_UTMP_USER_PROCESS | READ_UTMP_NO_BOOT_TIME)) == 0
+      && strcmp (file, UTMP_FILE) == 0
+      && !have_boot_time (a))
+    {
+      struct timespec boot_time;
+      if (get_linux_boot_time_final_fallback (&boot_time) >= 0)
+        a = add_utmp (a, options,
+                      "reboot", strlen ("reboot"),
+                      "", 0,
+                      "~", strlen ("~"),
+                      "", 0,
+                      0, BOOT_TIME, boot_time, 0, 0, 0);
+    }
+
+#  endif
+
 #  if HAVE_SYS_SYSCTL_H && HAVE_SYSCTL \
       && defined CTL_KERN && defined KERN_BOOTTIME \
       && !defined __minix
@@ -683,12 +699,6 @@ get_boot_time_uncached (void)
     free (utmp);
   }
 
-  {
-    struct timespec boot_time;
-    if (get_linux_boot_time_final_fallback (&boot_time) >= 0)
-      return boot_time;
-  }
-
   /* We shouldn't get here.  */
   return (struct timespec) {0};
 }
diff --git a/m4/readutmp.m4 b/m4/readutmp.m4
index 827b573f46..c180374044 100644
--- a/m4/readutmp.m4
+++ b/m4/readutmp.m4
@@ -1,4 +1,4 @@
-# readutmp.m4 serial 26
+# readutmp.m4 serial 27
 dnl Copyright (C) 2002-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -40,6 +40,8 @@ AC_DEFUN([gl_READUTMP]
       fi
     fi
   fi
+  AC_REQUIRE([gl_CLOCK_TIME])
+  READUTMP_LIB="$READUTMP_LIB $CLOCK_TIME_LIB"
   AC_SUBST([READUTMP_LIB])
 
   gl_PREREQ_READUTMP_H




Reply via email to