]> Savannah Git Hosting - gnulib.git/commitdiff
readutmp: Return a boot time also on Alpine Linux.
authorBruno Haible <bruno@clisp.org>
Wed, 9 Aug 2023 20:27:16 +0000 (22:27 +0200)
committerBruno Haible <bruno@clisp.org>
Wed, 9 Aug 2023 20:27:16 +0000 (22:27 +0200)
* lib/readutmp.c: Include stat-time.h.
(SIZEOF): New macro.
(read_utmp_from_file) [__linux__]: Fake a BOOT_TIME entry by looking
at the time stamp of a specific file.
* modules/readutmp (Depends-on): Add stat-time.

ChangeLog
lib/readutmp.c
modules/readutmp

index 3725c3bf9ee3108543e3a89b39780fc0ac9ae937..c6e700185977ebfd88c7a279c2245e517336c7cd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2023-08-09  Bruno Haible  <bruno@clisp.org>
 
+       readutmp: Return a boot time also on Alpine Linux.
+       * lib/readutmp.c: Include stat-time.h.
+       (SIZEOF): New macro.
+       (read_utmp_from_file) [__linux__]: Fake a BOOT_TIME entry by looking
+       at the time stamp of a specific file.
+       * modules/readutmp (Depends-on): Add stat-time.
+
        readutmp: Fix boot time in VMs after sleep state and date update.
        * lib/readutmp.c (read_utmp_from_file): New function, extracted from
        read_utmp.
index f7a839a1ebe2591f85e2e71a3968e1b9eab0b15e..2eb3395e0c436b34dd7e1f422ebce2a3890e8b87 100644 (file)
@@ -38,6 +38,7 @@
 # include <time.h>
 #endif
 
+#include "stat-time.h"
 #include "xalloc.h"
 
 /* Each of the FILE streams in this file is only used in a single thread.  */
 /* Size of the ut->ut_host member.  */
 #define UT_HOST_SIZE  sizeof (((struct UTMP_STRUCT_NAME *) 0)->ut_host)
 
+#define SIZEOF(a) (sizeof(a)/sizeof(a[0]))
+
 #if 8 <= __GNUC__
 # pragma GCC diagnostic ignored "-Wsizeof-pointer-memaccess"
 #endif
@@ -388,6 +391,51 @@ read_utmp_from_file (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf,
 
   END_UTMP_ENT ();
 
+#  if defined __linux__
+  /* On Alpine Linux, UTMP_FILE is not filled.  It is always empty.
+     So, fake a BOOT_TIME entry, by getting the time stamp of a file that
+     gets touched only during the boot process.  */
+  if ((options & (READ_UTMP_USER_PROCESS | READ_UTMP_NO_BOOT_TIME)) == 0
+      && strcmp (file, UTMP_FILE) == 0)
+    {
+      bool have_boot_time = false;
+      for (idx_t i = 0; i < a.filled; i++)
+        {
+          struct gl_utmp *ut = &a.utmp[i];
+          if (UT_TYPE_BOOT_TIME (ut))
+            {
+              have_boot_time = true;
+              break;
+            }
+        }
+      if (!have_boot_time)
+        {
+          const char * const boot_touched_files[] =
+            {
+              "/var/lib/systemd/random-seed", /* seen on distros with systemd */
+              "/var/run/utmp",                /* seen on distros with OpenRC */
+              "/var/lib/random-seed"          /* seen on older distros */
+            };
+          for (idx_t i = 0; i < SIZEOF (boot_touched_files); i++)
+            {
+              const char *filename = boot_touched_files[i];
+              struct stat statbuf;
+              if (stat (filename, &statbuf) >= 0)
+                {
+                  struct timespec boot_time = get_stat_mtime (&statbuf);
+                  a = add_utmp (a, options,
+                                "reboot", strlen ("reboot"),
+                                "", 0,
+                                "~", strlen ("~"),
+                                "", 0,
+                                0, BOOT_TIME, boot_time, 0, 0, 0);
+                  break;
+                }
+            }
+        }
+    }
+#  endif
+
 # else /* old FreeBSD, OpenBSD, HP-UX */
 
   FILE *f = fopen (file, "re");
index 15c63a3d5ed3ba1ba00d741aa1d1cdc7314bd5ba..21f6de5777bd5fac11227e030fc8698bb54ccfbe 100644 (file)
@@ -11,6 +11,7 @@ Depends-on:
 extensions
 fopen-gnu
 idx
+stat-time
 stdbool
 stdint
 strnlen