2023-08-09 Bruno Haible <bruno@clisp.org>
+ readutmp: Return a boot time also on OpenBSD.
+ * lib/readutmp.h (BOOT_TIME, USER_PROCESS): Provide fallback
+ definitions.
+ * lib/readutmp.c (read_utmp_from_file) [__OpenBSD__]: Fake a BOOT_TIME
+ entry by looking at the time stamp of a specific file.
+
readutmp: Return a boot time also on Alpine Linux.
* lib/readutmp.c: Include stat-time.h.
(SIZEOF): New macro.
return -1;
}
+# if defined __OpenBSD__
+ /* On OpenBSD, UTMP_FILE is not filled. It contains only dummy entries.
+ 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)
+ {
+ /* OpenBSD's 'struct utmp' does not have an ut_type field. */
+ bool have_boot_time = false;
+ if (!have_boot_time)
+ {
+ const char * const boot_touched_files[] =
+ {
+ "/var/db/host.random",
+ "/var/run/utmp"
+ };
+ 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
+
# endif
a = finish_utmp (a);
# define WTMP_FILE "/etc/wtmp"
#endif
+/* Some platforms, such as OpenBSD, don't have an ut_type field and don't have
+ the BOOT_TIME and USER_PROCESS macros. But we want to support them in
+ 'struct gl_utmp'. */
+#if !(HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_TYPE : HAVE_STRUCT_UTMP_UT_TYPE)
+# define BOOT_TIME 2
+# define USER_PROCESS 0
+#endif
+
/* Macros that test (UT)->ut_type. */
#ifdef BOOT_TIME
# define UT_TYPE_BOOT_TIME(UT) UT_TYPE_EQ (UT, BOOT_TIME)