]> Savannah Git Hosting - gnulib.git/commitdiff
readutmp: switch new struct to struct timespec
authorPaul Eggert <eggert@cs.ucla.edu>
Thu, 3 Aug 2023 23:01:50 +0000 (16:01 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Fri, 4 Aug 2023 01:20:51 +0000 (18:20 -0700)
* lib/readutmp.c (get_boot_time_uncached, get_boot_time)
(add_utmp, read_utmp):
Use struct timespec, not struct timeval.
* lib/readutmp.h: Always include <time.h>, for struct timespec.
Simplify when utmp.h and utmpx.h are included.
(struct gl_utmp): Use the same struct for both the
systemd and the dummy version.  Reorder members, and
use proper pid_t type for ut_session.  Rename ut_tv to ut_ts
and make it a struct timespec.  All uses changed.
(HAVE_GL_UTMP): New macro.  Use it where appropriate, instead
of READUTMP_USE_SYSTEMD.
(UT_USER, HAVE_STRUCT_XTMP_UT_EXIT, HAVE_STRUCT_XTMP_UT_ID)
(HAVE_STRUCT_XTMP_UT_PID, HAVE_STRUCT_XTMP_UT_HOST):
Simplify.
* modules/readutmp (Depends-on): Add time-h, timespec_get.
Remove sys_type.  Sort.

ChangeLog
lib/readutmp.c
lib/readutmp.h
modules/readutmp

index 44b80d8c6107e695c020d33a6afa0e635fbf78a5..133f49df97c29506c9f477802e2b5944a26986a0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,23 @@
 2023-08-03  Paul Eggert  <eggert@cs.ucla.edu>
 
+       readutmp: switch new struct to struct timespec
+       * lib/readutmp.c (get_boot_time_uncached, get_boot_time)
+       (add_utmp, read_utmp):
+       Use struct timespec, not struct timeval.
+       * lib/readutmp.h: Always include <time.h>, for struct timespec.
+       Simplify when utmp.h and utmpx.h are included.
+       (struct gl_utmp): Use the same struct for both the
+       systemd and the dummy version.  Reorder members, and
+       use proper pid_t type for ut_session.  Rename ut_tv to ut_ts
+       and make it a struct timespec.  All uses changed.
+       (HAVE_GL_UTMP): New macro.  Use it where appropriate, instead
+       of READUTMP_USE_SYSTEMD.
+       (UT_USER, HAVE_STRUCT_XTMP_UT_EXIT, HAVE_STRUCT_XTMP_UT_ID)
+       (HAVE_STRUCT_XTMP_UT_PID, HAVE_STRUCT_XTMP_UT_HOST):
+       Simplify.
+       * modules/readutmp (Depends-on): Add time-h, timespec_get.
+       Remove sys_type.  Sort.
+
        readutmp: fix # indentation
        * lib/readutmp.h: Change # indentation to standard Gnulib style.
 
index 97e92e69afb92a3ec9cebe6f859d7389b911ef41..113382c636d425f49606730a9d13f21fd1499c63 100644 (file)
@@ -93,7 +93,7 @@ desirable_utmp_entry (STRUCT_UTMP const *ut, int options)
 # if READUTMP_USE_SYSTEMD
 /* Use systemd and Linux /proc and kernel APIs.  */
 
-static struct timeval
+static struct timespec
 get_boot_time_uncached (void)
 {
   /* /proc/uptime contains the uptime with a resolution of 0.01 sec.  */
@@ -111,19 +111,22 @@ get_boot_time_uncached (void)
           double uptime = strtod (buf, &endptr);
           if (endptr > buf)
             {
-              struct timeval result;
-              if (gettimeofday (&result, NULL) >= 0)
+              struct timespec result;
+              if (0 <= timespec_get (&result, TIME_UTC))
                 {
-                  long uptime_sec = (long) uptime;
-                  int uptime_usec =
-                    (int) ((uptime - (double) uptime_sec) * 1000000.0 + 0.5);
-                  if (result.tv_usec < uptime_usec)
+                  time_t uptime_sec = uptime;
+                  struct timespec up =
                     {
-                      result.tv_usec += 1000000;
+                      .tv_sec = uptime_sec,
+                      .tv_nsec = (uptime - uptime_sec) * 1e9 + 0.5
+                    };
+                  if (result.tv_nsec < up.tv_nsec)
+                    {
+                      result.tv_nsec += 1000000000;
                       result.tv_sec -= 1;
                     }
-                  result.tv_sec -= uptime_sec;
-                  result.tv_usec -= uptime_usec;
+                  result.tv_sec -= up.tv_sec;
+                  result.tv_nsec -= up.tv_nsec;
                   return result;
                 }
             }
@@ -134,8 +137,8 @@ get_boot_time_uncached (void)
   struct sysinfo info;
   if (sysinfo (&info) >= 0)
     {
-      struct timeval result;
-      if (gettimeofday (&result, NULL) >= 0)
+      struct timespec result;
+      if (0 <= timespec_get (&result, TIME_UTC))
         {
           result.tv_sec -= info.uptime;
           return result;
@@ -143,19 +146,19 @@ get_boot_time_uncached (void)
     }
 
   /* We shouldn't get here.  */
-  return (struct timeval) { .tv_sec = 0, .tv_usec = 0 };
+  return (struct timespec) {0};
 }
 
-static struct timeval
+static struct timespec
 get_boot_time (void)
 {
-  static int cached;
-  static struct timeval boot_time;
+  static bool cached;
+  static struct timespec boot_time;
 
   if (!cached)
     {
+      cached = true;
       boot_time = get_boot_time_uncached ();
-      cached = 1;
     }
   return boot_time;
 }
@@ -252,7 +255,7 @@ struct utmp_alloc
 static struct utmp_alloc
 add_utmp (struct utmp_alloc a, int options,
           char const *user, char const *id, char const *line, pid_t pid,
-          short type, struct timeval t, char const *host, long session)
+          short type, struct timespec ts, char const *host, long session)
 {
   if (!user) user = "";
   if (!host) host = "";
@@ -277,11 +280,11 @@ add_utmp (struct utmp_alloc a, int options,
   ut->ut_user = p = memcpy (p - usersize, user, usersize);
   ut->ut_id   = p = memcpy (p -   idsize,   id,   idsize);
   ut->ut_line = p = memcpy (p - linesize, line, linesize);
-  ut->ut_pid = pid;
-  ut->ut_type = type;
-  ut->ut_tv = t;
   ut->ut_host = memcpy (p - hostsize, line, hostsize);
+  ut->ut_ts = ts;
+  ut->ut_pid = pid;
   ut->ut_session = session;
+  ut->ut_type = type;
   if (desirable_utmp_entry (ut, options))
     {
       /* Now that UT has been checked, relocate its string slots to be
@@ -323,9 +326,9 @@ read_utmp (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf,
           uint64_t start_usec;
           if (sd_session_get_start_time (session, &start_usec) < 0)
             start_usec = 0;
-          struct timeval start_tv;
-          start_tv.tv_sec = start_usec / 1000000;
-          start_tv.tv_usec = start_usec % 1000000;
+          struct timespec start_ts;
+          start_ts.tv_sec = start_usec / 1000000;
+          start_ts.tv_nsec = start_usec % 1000000 * 1000;
 
           char *seat;
           if (sd_session_get_seat (session, &seat) < 0)
@@ -346,19 +349,9 @@ read_utmp (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf,
                   if (sd_session_get_service (session, &service) < 0)
                     service = NULL;
 
-                  char *pty;
                   uid_t uid;
-                  if (sd_session_get_uid (session, &uid) >= 0)
-                    {
-                      struct timespec start_ts =
-                        {
-                          .tv_sec = start_tv.tv_sec,
-                          .tv_nsec = start_tv.tv_usec * 1000
-                        };
-                      pty = guess_pty_name (uid, start_ts);
-                    }
-                  else
-                    pty = NULL;
+                  char *pty = (sd_session_get_uid (session, &uid) < 0 ? NULL
+                               : guess_pty_name (uid, start_ts));
 
                   if (service != NULL && pty != NULL)
                     {
@@ -422,11 +415,11 @@ read_utmp (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf,
               if (seat != NULL)
                 a = add_utmp (a, options, user, session, seat,
                               leader_pid /* the best we have */,
-                              USER_PROCESS, start_tv, host, leader_pid);
+                              USER_PROCESS, start_ts, host, leader_pid);
               if (tty != NULL)
                 a = add_utmp (a, options, user, session, tty,
                               leader_pid /* the best we have */,
-                              USER_PROCESS, start_tv, host, leader_pid);
+                              USER_PROCESS, start_ts, host, leader_pid);
 
               free (host);
               free (user);
index da7225152cdffbc33665894ae2486a7feccc5a41..b3cfaeb67c7238c0e82a80119d37937d577b653e 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <stdlib.h>
 #include <sys/types.h>
+#include <time.h>
 
 /* AIX 4.3.3 has both utmp.h and utmpx.h, but only struct utmp
    has the ut_exit member.  */
 # undef HAVE_UTMPX_H
 #endif
 
-#if READUTMP_USE_SYSTEMD
+/* HPUX 10.20 needs utmp.h, for the definition of e.g., UTMP_FILE.  */
+#if HAVE_UTMP_H
+# include <utmp.h>
+#endif
 
-/* Get 'struct timeval'.  */
-# include <sys/time.h>
+/* Needed for BOOT_TIME and USER_PROCESS.  */
+#if HAVE_UTMPX_H
+# if defined _THREAD_SAFE && defined UTMP_DATA_INIT
+    /* When including both utmp.h and utmpx.h on AIX 4.3, with _THREAD_SAFE
+       defined, work around the duplicate struct utmp_data declaration.  */
+#  define utmp_data gl_aix_4_3_workaround_utmp_data
+# endif
+# include <utmpx.h>
+#endif
+
+#if READUTMP_USE_SYSTEMD || ! (HAVE_UTMPX_H || HAVE_UTMP_H)
 
-/* Type for the entries returned by read_utmp.  */
 struct gl_utmp
 {
   /* All 'char *' here are of arbitrary length and malloc-allocated.  */
   char *ut_user;                /* User name */
   char *ut_id;                  /* Session ID */
   char *ut_line;                /* seat / device */
+  char *ut_host;                /* for remote sessions: user@host or host */
+  struct timespec ut_ts;        /* time */
   pid_t ut_pid;                 /* process ID of ? */
+  pid_t ut_session;             /* process ID of session leader */
   short ut_type;                /* BOOT_TIME or USER_PROCESS */
-  struct timeval ut_tv;         /* time */
-  char *ut_host;                /* for remote sessions: user@host or host */
-  long ut_session;              /* process ID of session leader */
 };
 
-/* Get values for ut_type: BOOT_TIME, USER_PROCESS.  */
-# include <utmpx.h>
-
+# define HAVE_GL_UTMP 1
 # define UTMP_STRUCT_NAME gl_utmp
-# define UT_TIME_MEMBER(UT) ((UT)->ut_tv.tv_sec)
+# define UT_TIME_MEMBER(UT) ((UT)->ut_ts.tv_sec)
 # define UT_EXIT_E_TERMINATION(UT) 0
 # define UT_EXIT_E_EXIT(UT) 0
 
@@ -90,16 +100,6 @@ struct gl_utmp
    ⎣ ut_ss        struct sockaddr_storage    NetBSD, Minix
  */
 
-# if HAVE_UTMP_H
-    /* HPUX 10.20 needs utmp.h, for the definition of e.g., UTMP_FILE.  */
-#  include <utmp.h>
-# endif
-# if defined _THREAD_SAFE && defined UTMP_DATA_INIT
-    /* When including both utmp.h and utmpx.h on AIX 4.3, with _THREAD_SAFE
-       defined, work around the duplicate struct utmp_data declaration.  */
-#  define utmp_data gl_aix_4_3_workaround_utmp_data
-# endif
-# include <utmpx.h>
 # define UTMP_STRUCT_NAME utmpx
 # define UT_TIME_MEMBER(UT) ((UT)->ut_tv.tv_sec)
 # define SET_UTMP_ENT setutxent
@@ -150,12 +150,11 @@ struct gl_utmp
    ⎣ ut_addr_v6   [u]int[4]                  glibc, musl, Android
  */
 
-# include <utmp.h>
 # if !HAVE_DECL_GETUTENT
     struct utmp *getutent (void);
 # endif
 # define UTMP_STRUCT_NAME utmp
-# define UT_TIME_MEMBER(UT) ((UT)->ut_time)
+# define UT_TIME_MEMBER(UT) ((UT)->ut_ts.tv_sec)
 # define SET_UTMP_ENT setutent
 # define GET_UTMP_ENT getutent
 # define END_UTMP_ENT endutent
@@ -175,94 +174,34 @@ struct gl_utmp
 #  define UT_EXIT_E_EXIT(UT) 0
 # endif
 
-#else
-
-/* Provide a dummy fallback.  */
-
-/* Get 'struct timeval'.  */
-# include <sys/time.h>
-
-struct gl_utmp
-{
-  char ut_user[1];
-  char ut_line[1];
-  struct timeval ut_tv;
-};
-# define UTMP_STRUCT_NAME gl_utmp
-# define UT_TIME_MEMBER(UT) ((UT)->ut_tv.tv_sec)
-# define UT_EXIT_E_TERMINATION(UT) 0
-# define UT_EXIT_E_EXIT(UT) 0
-
 #endif
 
 /* Accessor macro for the member named ut_user or ut_name.  */
-#if READUTMP_USE_SYSTEMD
-
-# define UT_USER(UT) ((UT)->ut_user)
-
-#elif HAVE_UTMPX_H
-
-# if HAVE_STRUCT_UTMPX_UT_USER
-#  define UT_USER(UT) ((UT)->ut_user)
-# endif
-# if HAVE_STRUCT_UTMPX_UT_NAME
-#  undef UT_USER
-#  define UT_USER(UT) ((UT)->ut_name)
-# endif
-
-#elif HAVE_UTMP_H
-
-# if HAVE_STRUCT_UTMP_UT_USER
-#  define UT_USER(UT) ((UT)->ut_user)
-# endif
-# if HAVE_STRUCT_UTMP_UT_NAME
-#  undef UT_USER
-#  define UT_USER(UT) ((UT)->ut_name)
-# endif
-
-#else /* dummy fallback */
-
+#if (!HAVE_GL_UTMP \
+     && (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_NAME \
+         : HAVE_UTMP_H && HAVE_STRUCT_UTMP_UT_NAME))
+# define UT_USER(UT) ((UT)->ut_name)
+#else
 # define UT_USER(UT) ((UT)->ut_user)
-
 #endif
 
-#if READUTMP_USE_SYSTEMD
-# define HAVE_STRUCT_XTMP_UT_EXIT 0
-#else
-# define HAVE_STRUCT_XTMP_UT_EXIT \
-     (HAVE_STRUCT_UTMP_UT_EXIT \
-      || HAVE_STRUCT_UTMPX_UT_EXIT)
-#endif
+#define HAVE_STRUCT_XTMP_UT_EXIT \
+  (!HAVE_GL_UTMP && (HAVE_STRUCT_UTMP_UT_EXIT || HAVE_STRUCT_UTMPX_UT_EXIT)
 
-#if READUTMP_USE_SYSTEMD
-# define HAVE_STRUCT_XTMP_UT_ID 1
-#else
-# define HAVE_STRUCT_XTMP_UT_ID \
-     (HAVE_STRUCT_UTMP_UT_ID \
-      || HAVE_STRUCT_UTMPX_UT_ID)
-#endif
+#define HAVE_STRUCT_XTMP_UT_ID \
+  (HAVE_GL_UTMP || HAVE_STRUCT_UTMP_UT_ID || HAVE_STRUCT_UTMPX_UT_ID)
 
-#if READUTMP_USE_SYSTEMD
-# define HAVE_STRUCT_XTMP_UT_PID 1
-#else
-# define HAVE_STRUCT_XTMP_UT_PID \
-     (HAVE_STRUCT_UTMP_UT_PID \
-      || HAVE_STRUCT_UTMPX_UT_PID)
-#endif
+#define HAVE_STRUCT_XTMP_UT_PID \
+  (HAVE_GL_UTMP || HAVE_STRUCT_UTMP_UT_PID || HAVE_STRUCT_UTMPX_UT_PID)
 
-#if READUTMP_USE_SYSTEMD
-# define HAVE_STRUCT_XTMP_UT_HOST 1
-#else
-# define HAVE_STRUCT_XTMP_UT_HOST \
-     (HAVE_STRUCT_UTMP_UT_HOST \
-      || HAVE_STRUCT_UTMPX_UT_HOST)
-#endif
+#define HAVE_STRUCT_XTMP_UT_HOST \
+  (HAVE_GL_UTMP || HAVE_STRUCT_UTMP_UT_HOST || HAVE_STRUCT_UTMPX_UT_HOST)
 
 /* Type of entry returned by read_utmp().  */
 typedef struct UTMP_STRUCT_NAME STRUCT_UTMP;
 
 /* Size of the UT_USER (ut) member, or -1 if unbounded.  */
-#if READUTMP_USE_SYSTEMD
+#if HAVE_GL_UTMP
 enum { UT_USER_SIZE = -1 };
 #else
 enum { UT_USER_SIZE = sizeof UT_USER ((STRUCT_UTMP *) 0) };
@@ -270,7 +209,7 @@ enum { UT_USER_SIZE = sizeof UT_USER ((STRUCT_UTMP *) 0) };
 #endif
 
 /* Size of the ut->ut_id member, or -1 if unbounded.  */
-#if READUTMP_USE_SYSTEMD
+#if HAVE_GL_UTMP
 enum { UT_ID_SIZE = -1 };
 #else
 enum { UT_ID_SIZE = sizeof (((STRUCT_UTMP *) 0)->ut_id) };
@@ -278,7 +217,7 @@ enum { UT_ID_SIZE = sizeof (((STRUCT_UTMP *) 0)->ut_id) };
 #endif
 
 /* Size of the ut->ut_line member, or -1 if unbounded.  */
-#if READUTMP_USE_SYSTEMD
+#if HAVE_GL_UTMP
 enum { UT_LINE_SIZE = -1 };
 #else
 enum { UT_LINE_SIZE = sizeof (((STRUCT_UTMP *) 0)->ut_line) };
@@ -286,7 +225,7 @@ enum { UT_LINE_SIZE = sizeof (((STRUCT_UTMP *) 0)->ut_line) };
 #endif
 
 /* Size of the ut->ut_host member, or -1 if unbounded.  */
-#if READUTMP_USE_SYSTEMD
+#if HAVE_GL_UTMP
 enum { UT_HOST_SIZE = -1 };
 #else
 enum { UT_HOST_SIZE = sizeof (((STRUCT_UTMP *) 0)->ut_host) };
@@ -330,7 +269,7 @@ enum { UT_HOST_SIZE = sizeof (((STRUCT_UTMP *) 0)->ut_host) };
 
 /* Accessor macros for the member named ut_type.  */
 
-#if READUTMP_USE_SYSTEMD || HAVE_STRUCT_UTMP_UT_TYPE || HAVE_STRUCT_UTMPX_UT_TYPE
+#if HAVE_GL_UTMP || HAVE_STRUCT_UTMP_UT_TYPE || HAVE_STRUCT_UTMPX_UT_TYPE
 # define UT_TYPE_EQ(UT, V) ((UT)->ut_type == (V))
 # define UT_TYPE_NOT_DEFINED 0
 #else
index 534ce4fa19367578bbcd01032a34cfafbedec93f..15c63a3d5ed3ba1ba00d741aa1d1cdc7314bd5ba 100644 (file)
@@ -9,14 +9,15 @@ m4/systemd.m4
 
 Depends-on:
 extensions
+fopen-gnu
 idx
-xalloc
 stdbool
 stdint
 strnlen
-sys_time
-fopen-gnu
+time-h
+timespec_get
 unlocked-io-internal
+xalloc
 
 configure.ac:
 gl_READUTMP