From 906e4b18e64abab3a8c2f261642b48222dc79333 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Mon, 31 Jul 2023 16:13:11 +0200 Subject: [PATCH] readutmp: Make the header file and function usable on all platforms. * lib/readutmp.h (struct gl_utmp, UTMP_STRUCT_NAME, UT_TIME_MEMBER, UT_EXIT_E_TERMINATION, UT_EXIT_E_EXIT, UT_USER): Provide fallback definitions. (READ_UTMP_SUPPORTED): New macro. * lib/readutmp.c (read_utmp) [!READ_UTMP_SUPPORTED]: Provide a dummy definition. * modules/readutmp (Depends-on): Add sys_time. (configure.ac): Remove conditional. (Makefile.am): Compile readutmp.c on all platforms. (Include): Include readutmp.h on all platforms. * tests/test-readutmp.c: Include readutmp.h on all platforms. (main): Invoke read_utmp on all platforms. --- ChangeLog | 16 +++++++++++++++ lib/readutmp.c | 24 ++++++++++++++++++----- lib/readutmp.h | 36 ++++++++++++++++++++++++++++++++++ modules/readutmp | 9 ++------- tests/test-readutmp.c | 45 ++++++++++++++++--------------------------- 5 files changed, 90 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index 81269fbbd5..d3bc0c13ae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2023-07-31 Bruno Haible + + readutmp: Make the header file and function usable on all platforms. + * lib/readutmp.h (struct gl_utmp, UTMP_STRUCT_NAME, UT_TIME_MEMBER, + UT_EXIT_E_TERMINATION, UT_EXIT_E_EXIT, UT_USER): Provide fallback + definitions. + (READ_UTMP_SUPPORTED): New macro. + * lib/readutmp.c (read_utmp) [!READ_UTMP_SUPPORTED]: Provide a dummy + definition. + * modules/readutmp (Depends-on): Add sys_time. + (configure.ac): Remove conditional. + (Makefile.am): Compile readutmp.c on all platforms. + (Include): Include readutmp.h on all platforms. + * tests/test-readutmp.c: Include readutmp.h on all platforms. + (main): Invoke read_utmp on all platforms. + 2023-07-30 Bruno Haible readutmp: Add tests. diff --git a/lib/readutmp.c b/lib/readutmp.c index acffe1000e..af43d1ad6b 100644 --- a/lib/readutmp.c +++ b/lib/readutmp.c @@ -61,6 +61,8 @@ extract_trimmed_name (const STRUCT_UTMP *ut) return trimmed_name; } +#if READ_UTMP_SUPPORTED + /* Is the utmp entry U desired by the user who asked for OPTIONS? */ static bool @@ -77,12 +79,12 @@ desirable_utmp_entry (STRUCT_UTMP const *u, int options) return true; } -#ifdef UTMP_NAME_FUNCTION +# if defined UTMP_NAME_FUNCTION static void copy_utmp_entry (STRUCT_UTMP *dst, STRUCT_UTMP *src) { -#if __GLIBC__ && _TIME_BITS == 64 +# if __GLIBC__ && _TIME_BITS == 64 /* Convert from external form in SRC to internal form in DST. It is OK to convert now, rather than earlier, before desirable_utmp_entry was invoked, because desirable_utmp_entry @@ -119,9 +121,9 @@ copy_utmp_entry (STRUCT_UTMP *dst, STRUCT_UTMP *src) dst->ut_tv.tv_sec = s->ut_tv.tv_sec; dst->ut_tv.tv_usec = s->ut_tv.tv_usec; memcpy (&dst->ut_addr_v6, s->ut_addr_v6, sizeof dst->ut_addr_v6); -#else +# else *dst = *src; -#endif +# endif } int @@ -158,7 +160,7 @@ read_utmp (char const *file, size_t *n_entries, STRUCT_UTMP **utmp_buf, return 0; } -#else +# else int read_utmp (char const *file, size_t *n_entries, STRUCT_UTMP **utmp_buf, @@ -198,4 +200,16 @@ read_utmp (char const *file, size_t *n_entries, STRUCT_UTMP **utmp_buf, return 0; } +# endif + +#else /* dummy fallback */ + +int +read_utmp (char const *file, size_t *n_entries, STRUCT_UTMP **utmp_buf, + int options) +{ + errno = ENOSYS; + return -1; +} + #endif diff --git a/lib/readutmp.h b/lib/readutmp.h index 7d2a628135..d710699525 100644 --- a/lib/readutmp.h +++ b/lib/readutmp.h @@ -38,6 +38,7 @@ # endif # if HAVE_UTMPX_H + # if HAVE_UTMP_H /* HPUX 10.20 needs utmp.h, for the definition of e.g., UTMP_FILE. */ # include @@ -114,6 +115,24 @@ # endif # endif +# else + +/* Provide a dummy fallback. */ + +/* Get 'struct timeval'. */ +# include + +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_PTR) ((UT_PTR)->ut_tv.tv_sec) +# define UT_EXIT_E_TERMINATION(U) 0 +# define UT_EXIT_E_EXIT(U) 0 + # endif /* Accessor macro for the member named ut_user or ut_name. */ @@ -137,6 +156,10 @@ # define UT_USER(Utmp) ((Utmp)->ut_name) # endif +# else /* dummy fallback */ + +# define UT_USER(Utmp) ((Utmp)->ut_user) + # endif # define HAVE_STRUCT_XTMP_UT_EXIT \ @@ -151,10 +174,14 @@ (HAVE_STRUCT_UTMP_UT_PID \ || HAVE_STRUCT_UTMPX_UT_PID) +/* Type of entry returned by read_utmp(). */ typedef struct UTMP_STRUCT_NAME STRUCT_UTMP; +/* Size of the UT_USER (ut) member. */ enum { UT_USER_SIZE = sizeof UT_USER ((STRUCT_UTMP *) 0) }; +/* Definition of UTMP_FILE and WTMP_FILE. */ + # if !defined UTMP_FILE && defined _PATH_UTMP # define UTMP_FILE _PATH_UTMP # endif @@ -181,12 +208,15 @@ enum { UT_USER_SIZE = sizeof UT_USER ((STRUCT_UTMP *) 0) }; # define WTMP_FILE "/etc/wtmp" # endif +/* Accessor macro for the member named ut_pid. */ # if HAVE_STRUCT_XTMP_UT_PID # define UT_PID(U) ((U)->ut_pid) # else # define UT_PID(U) 0 # endif +/* Accessor macros for the member named ut_type. */ + # if HAVE_STRUCT_UTMP_UT_TYPE || HAVE_STRUCT_UTMPX_UT_TYPE # define UT_TYPE_EQ(U, V) ((U)->ut_type == (V)) # define UT_TYPE_NOT_DEFINED 0 @@ -207,11 +237,17 @@ enum { UT_USER_SIZE = sizeof UT_USER ((STRUCT_UTMP *) 0) }; # define UT_TYPE_USER_PROCESS(U) 0 # endif +/* Determines whether an entry *U corresponds to a user process. */ # define IS_USER_PROCESS(U) \ (UT_USER (U)[0] \ && (UT_TYPE_USER_PROCESS (U) \ || (UT_TYPE_NOT_DEFINED && UT_TIME_MEMBER (U) != 0))) +/* Define if read_utmp is not just a dummy. */ +# if HAVE_UTMPX_H || HAVE_UTMP_H +# define READ_UTMP_SUPPORTED 1 +# endif + /* Options for read_utmp. */ enum { diff --git a/modules/readutmp b/modules/readutmp index 7f84f189ea..4b2de331dc 100644 --- a/modules/readutmp +++ b/modules/readutmp @@ -11,23 +11,18 @@ extensions xalloc stdbool stdint +sys_time fopen-gnu unlocked-io-internal configure.ac: gl_READUTMP -gl_CONDITIONAL([GL_COND_OBJ_READUTMP], - [test $ac_cv_header_utmp_h = yes || test $ac_cv_header_utmpx_h = yes]) Makefile.am: -if GL_COND_OBJ_READUTMP lib_SOURCES += readutmp.c -endif Include: -#if HAVE_UTMPX_H || HAVE_UTMP_H -#include "readutmp.h" -#endif +"readutmp.h" License: GPL diff --git a/tests/test-readutmp.c b/tests/test-readutmp.c index 1dbf70b351..933808b257 100644 --- a/tests/test-readutmp.c +++ b/tests/test-readutmp.c @@ -18,25 +18,23 @@ #include -#if HAVE_UTMPX_H || HAVE_UTMP_H +#include "readutmp.h" -# include "readutmp.h" +#include +#include +#include +#include +#include -# include -# include -# include -# include -# include +#include "xalloc.h" -# include "xalloc.h" +#define ELEMENT STRUCT_UTMP +#define COMPARE(entry1, entry2) \ + _GL_CMP (UT_TIME_MEMBER (entry1), UT_TIME_MEMBER (entry2)) +#define STATIC static +#include "array-mergesort.h" -# define ELEMENT STRUCT_UTMP -# define COMPARE(entry1, entry2) \ - _GL_CMP (UT_TIME_MEMBER (entry1), UT_TIME_MEMBER (entry2)) -# define STATIC static -# include "array-mergesort.h" - -# include "macros.h" +#include "macros.h" int main (int argc, char *argv[]) @@ -46,7 +44,11 @@ main (int argc, char *argv[]) if (read_utmp (UTMP_FILE, &num_entries, &entries, 0) < 0) { + #if READ_UTMP_SUPPORTED fprintf (stderr, "Skipping test: cannot open %s\n", UTMP_FILE); + #else + fprintf (stderr, "Skipping test: neither nor is available\n"); + #endif return 77; } @@ -99,16 +101,3 @@ main (int argc, char *argv[]) return 0; } - -#else - -# include - -int -main () -{ - fprintf (stderr, "Skipping test: neither nor is available\n"); - return 77; -} - -#endif -- 2.39.5