From: Bruno Haible Date: Wed, 9 Aug 2023 20:27:16 +0000 (+0200) Subject: readutmp: Return a boot time also on Alpine Linux. X-Git-Tag: v1.0~945 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=51f5c00413f3b2fc42520d4f520a8b9181afe531;p=gnulib.git 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. --- diff --git a/ChangeLog b/ChangeLog index 3725c3bf9e..c6e7001859 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2023-08-09 Bruno Haible + 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. diff --git a/lib/readutmp.c b/lib/readutmp.c index f7a839a1eb..2eb3395e0c 100644 --- a/lib/readutmp.c +++ b/lib/readutmp.c @@ -38,6 +38,7 @@ # include #endif +#include "stat-time.h" #include "xalloc.h" /* Each of the FILE streams in this file is only used in a single thread. */ @@ -132,6 +133,8 @@ /* 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"); diff --git a/modules/readutmp b/modules/readutmp index 15c63a3d5e..21f6de5777 100644 --- a/modules/readutmp +++ b/modules/readutmp @@ -11,6 +11,7 @@ Depends-on: extensions fopen-gnu idx +stat-time stdbool stdint strnlen