Thanks, I installed the attached to simplify a bit further. A nice
consequence of these recent changes is that we get to remove some pragmas.
The first patch is for Gnulib; the other two are for Coreutils.
From e14d7e198f96039dbc4fb2118739e6ca1fc4cec6 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Tue, 8 Aug 2023 19:29:55 -0700
Subject: [PATCH] readutmp: omit pragma
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* lib/readutmp.c: Omit -Sstringop-overread pragma.
It’s no longer needed now that extract_trimmed_name
no longer calls strnlen.
---
ChangeLog | 7 +++++++
lib/readutmp.c | 5 -----
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 199c818c18..40274c0a08 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2023-08-08 Paul Eggert <egg...@cs.ucla.edu>
+
+ readutmp: omit pragma
+ * lib/readutmp.c: Omit -Sstringop-overread pragma.
+ It’s no longer needed now that extract_trimmed_name
+ no longer calls strnlen.
+
2023-08-08 Bruno Haible <br...@clisp.org>
readutmp: Use classical implementation for files != /var/run/utmp.
diff --git a/lib/readutmp.c b/lib/readutmp.c
index 66b25bc7ae..31db4023a1 100644
--- a/lib/readutmp.c
+++ b/lib/readutmp.c
@@ -136,11 +136,6 @@
# pragma GCC diagnostic ignored "-Wsizeof-pointer-memaccess"
#endif
-/* Work around <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110884>. */
-#if 11 <= __GNUC__
-# pragma GCC diagnostic ignored "-Wstringop-overread"
-#endif
-
/* Copy UT->ut_user into storage obtained from malloc. Then remove any
trailing spaces from the copy, NUL terminate it, and return the copy. */
--
2.39.2
From 422dcd424ca6b5fbef8d3bd0088e8e9e3757a203 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Tue, 8 Aug 2023 19:32:49 -0700
Subject: [PATCH 1/2] pinky,who: omit pragma
* src/pinky.c, src/who.c:
Omit no-longer-needed -Wstringop-overread pragma.
---
src/pinky.c | 6 ------
src/who.c | 6 ------
2 files changed, 12 deletions(-)
diff --git a/src/pinky.c b/src/pinky.c
index 1429dd073..59c552bf1 100644
--- a/src/pinky.c
+++ b/src/pinky.c
@@ -426,12 +426,6 @@ print_heading (void)
putchar ('\n');
}
-/* Work around <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109614>,
- triggered by STREQ_LEN with a negative length. */
-#if 11 <= __GNUC__
-# pragma GCC diagnostic ignored "-Wstringop-overread"
-#endif
-
/* Display UTMP_BUF, which should have N entries. */
static void
diff --git a/src/who.c b/src/who.c
index 27a7904e1..074d2d5ad 100644
--- a/src/who.c
+++ b/src/who.c
@@ -570,12 +570,6 @@ print_heading (void)
_("PID"), _("COMMENT"), _("EXIT"));
}
-/* Work around <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109614>,
- triggered by STREQ_LEN with a negative length. */
-#if 11 <= __GNUC__
-# pragma GCC diagnostic ignored "-Wstringop-overread"
-#endif
-
/* Display UTMP_BUF, which should have N entries. */
static void
scan_entries (idx_t n, const STRUCT_UTMP *utmp_buf)
--
2.39.2
From ad823360267cbfb3f5b1b3e1438122e5c82eb0b2 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Tue, 8 Aug 2023 20:03:40 -0700
Subject: [PATCH 2/2] who: simplify based on readutmp changes
* src/pinky.c (time_string, print_entry, scan_entries, short_pinky):
* src/uptime.c (print_uptime, uptime):
* src/users.c (list_entries_users, users):
* src/who.c (UT_TYPE_RUN_LVL, UT_TYPE_INIT_PROCESS)
(UT_TYPE_LOGIN_PROCESS, UT_TYPE_DEAD_PROCESS, UT_TYPE_NEW_TIME)
(time_string, print_user, print_boottime)
(make_id_equals_comment, print_deadprocs, print_login)
(print_initspawn, print_clockchange, print_runlevel)
(list_entries_who, scan_entries, who):
Simplify, partly by using plain -> rather than macros.
---
src/pinky.c | 33 ++++++++++-----------------
src/uptime.c | 7 +++---
src/users.c | 5 ++---
src/who.c | 63 ++++++++++++++++++++++------------------------------
4 files changed, 44 insertions(+), 64 deletions(-)
diff --git a/src/pinky.c b/src/pinky.c
index 59c552bf1..5ad05e553 100644
--- a/src/pinky.c
+++ b/src/pinky.c
@@ -172,18 +172,10 @@ idle_string (time_t when)
/* Return a time string. */
static char const *
-time_string (const STRUCT_UTMP *utmp_ent)
+time_string (struct gl_utmp const *utmp_ent)
{
static char buf[INT_STRLEN_BOUND (intmax_t) + sizeof "-%m-%d %H:%M"];
-
- /* Don't take the address of UT_TIME_MEMBER directly.
- Ulrich Drepper wrote:
- "... GNU libc (and perhaps other libcs as well) have extended
- utmp file formats which do not use a simple time_t ut_time field.
- In glibc, ut_time is a macro which selects for backward compatibility
- the tv_sec member of a struct timeval value." */
- time_t t = UT_TIME_MEMBER (utmp_ent);
- struct tm *tmp = localtime (&t);
+ struct tm *tmp = localtime (&utmp_ent->ut_ts.tv_sec);
if (tmp)
{
@@ -191,13 +183,13 @@ time_string (const STRUCT_UTMP *utmp_ent)
return buf;
}
else
- return timetostr (t, buf);
+ return timetostr (utmp_ent->ut_ts.tv_sec, buf);
}
/* Display a line of information about UTMP_ENT. */
static void
-print_entry (const STRUCT_UTMP *utmp_ent)
+print_entry (struct gl_utmp const *utmp_ent)
{
struct stat stats;
time_t last_change;
@@ -234,15 +226,15 @@ print_entry (const STRUCT_UTMP *utmp_ent)
last_change = 0;
}
- if (strnlen (UT_USER (utmp_ent), 8) < 8)
- printf ("%-8s", UT_USER (utmp_ent));
+ char *ut_user = utmp_ent->ut_user;
+ if (strnlen (ut_user, 8) < 8)
+ printf ("%-8s", ut_user);
else
- fputs (UT_USER (utmp_ent), stdout);
+ fputs (ut_user, stdout);
if (include_fullname)
{
- char *name = UT_USER (utmp_ent);
- struct passwd *pw = getpwnam (name);
+ struct passwd *pw = getpwnam (ut_user);
if (pw == nullptr)
/* TRANSLATORS: Real name is unknown; at most 19 characters. */
printf (" %19s", _(" ???"));
@@ -429,7 +421,7 @@ print_heading (void)
/* Display UTMP_BUF, which should have N entries. */
static void
-scan_entries (idx_t n, const STRUCT_UTMP *utmp_buf,
+scan_entries (idx_t n, struct gl_utmp const *utmp_buf,
const int argc_names, char *const argv_names[])
{
if (hard_locale (LC_TIME))
@@ -453,7 +445,7 @@ scan_entries (idx_t n, const STRUCT_UTMP *utmp_buf,
if (argc_names)
{
for (int i = 0; i < argc_names; i++)
- if (STREQ (UT_USER (utmp_buf), argv_names[i]))
+ if (STREQ (utmp_buf->ut_user, argv_names[i]))
{
print_entry (utmp_buf);
break;
@@ -473,8 +465,7 @@ short_pinky (char const *filename,
const int argc_names, char *const argv_names[])
{
idx_t n_users;
- STRUCT_UTMP *utmp_buf = nullptr;
-
+ struct gl_utmp *utmp_buf;
if (read_utmp (filename, &n_users, &utmp_buf, 0) != 0)
error (EXIT_FAILURE, errno, "%s", quotef (filename));
diff --git a/src/uptime.c b/src/uptime.c
index ad1bbb9a1..22a3bdb19 100644
--- a/src/uptime.c
+++ b/src/uptime.c
@@ -45,7 +45,7 @@
proper_name ("Kaveh Ghazi")
static void
-print_uptime (idx_t n, const STRUCT_UTMP *this)
+print_uptime (idx_t n, struct gl_utmp const *this)
{
idx_t entries = 0;
time_t boot_time = 0;
@@ -106,7 +106,7 @@ print_uptime (idx_t n, const STRUCT_UTMP *this)
{
entries += IS_USER_PROCESS (this);
if (UT_TYPE_BOOT_TIME (this))
- boot_time = UT_TIME_MEMBER (this);
+ boot_time = this->ut_ts.tv_sec;
++this;
}
@@ -170,8 +170,7 @@ static _Noreturn void
uptime (char const *filename, int options)
{
idx_t n_users;
- STRUCT_UTMP *utmp_buf = nullptr;
-
+ struct gl_utmp *utmp_buf;
if (read_utmp (filename, &n_users, &utmp_buf, options) != 0)
error (EXIT_FAILURE, errno, "%s", quotef (filename));
diff --git a/src/users.c b/src/users.c
index 353c1765d..cdb766004 100644
--- a/src/users.c
+++ b/src/users.c
@@ -42,7 +42,7 @@ userid_compare (const void *v_a, const void *v_b)
}
static void
-list_entries_users (idx_t n, const STRUCT_UTMP *this)
+list_entries_users (idx_t n, struct gl_utmp const *this)
{
char **u = xinmalloc (n, sizeof *u);
idx_t i;
@@ -83,8 +83,7 @@ static void
users (char const *filename, int options)
{
idx_t n_users;
- STRUCT_UTMP *utmp_buf;
-
+ struct gl_utmp *utmp_buf;
if (read_utmp (filename, &n_users, &utmp_buf, options) != 0)
error (EXIT_FAILURE, errno, "%s", quotef (filename));
diff --git a/src/who.c b/src/who.c
index 074d2d5ad..293e3b770 100644
--- a/src/who.c
+++ b/src/who.c
@@ -50,31 +50,31 @@
proper_name ("Michael Stone")
#ifdef RUN_LVL
-# define UT_TYPE_RUN_LVL(U) UT_TYPE_EQ (U, RUN_LVL)
+# define UT_TYPE_RUN_LVL(U) ((U)->ut_type == RUN_LVL)
#else
# define UT_TYPE_RUN_LVL(U) false
#endif
#ifdef INIT_PROCESS
-# define UT_TYPE_INIT_PROCESS(U) UT_TYPE_EQ (U, INIT_PROCESS)
+# define UT_TYPE_INIT_PROCESS(U) ((U)->ut_type == INIT_PROCESS)
#else
# define UT_TYPE_INIT_PROCESS(U) false
#endif
#ifdef LOGIN_PROCESS
-# define UT_TYPE_LOGIN_PROCESS(U) UT_TYPE_EQ (U, LOGIN_PROCESS)
+# define UT_TYPE_LOGIN_PROCESS(U) ((U)->ut_type == LOGIN_PROCESS)
#else
# define UT_TYPE_LOGIN_PROCESS(U) false
#endif
#ifdef DEAD_PROCESS
-# define UT_TYPE_DEAD_PROCESS(U) UT_TYPE_EQ (U, DEAD_PROCESS)
+# define UT_TYPE_DEAD_PROCESS(U) ((U)->ut_type == DEAD_PROCESS)
#else
# define UT_TYPE_DEAD_PROCESS(U) false
#endif
#ifdef NEW_TIME
-# define UT_TYPE_NEW_TIME(U) UT_TYPE_EQ (U, NEW_TIME)
+# define UT_TYPE_NEW_TIME(U) ((U)->ut_type == NEW_TIME)
#else
# define UT_TYPE_NEW_TIME(U) false
#endif
@@ -212,18 +212,10 @@ idle_string (time_t when, time_t boottime)
/* Return a time string. */
static char const *
-time_string (const STRUCT_UTMP *utmp_ent)
+time_string (struct gl_utmp const *utmp_ent)
{
static char buf[INT_STRLEN_BOUND (intmax_t) + sizeof "-%m-%d %H:%M"];
-
- /* Don't take the address of UT_TIME_MEMBER directly.
- Ulrich Drepper wrote:
- "... GNU libc (and perhaps other libcs as well) have extended
- utmp file formats which do not use a simple time_t ut_time field.
- In glibc, ut_time is a macro which selects for backward compatibility
- the tv_sec member of a struct timeval value." */
- time_t t = UT_TIME_MEMBER (utmp_ent);
- struct tm *tmp = localtime (&t);
+ struct tm *tmp = localtime (&utmp_ent->ut_ts.tv_sec);
if (tmp)
{
@@ -231,7 +223,7 @@ time_string (const STRUCT_UTMP *utmp_ent)
return buf;
}
else
- return timetostr (t, buf);
+ return timetostr (utmp_ent->ut_ts.tv_sec, buf);
}
/* Print formatted output line. Uses mostly arbitrary field sizes, probably
@@ -327,7 +319,7 @@ is_tty_writable (struct stat const *pstat)
/* Send properly parsed USER_PROCESS info to print_line. The most
recent boot time is BOOTTIME. */
static void
-print_user (const STRUCT_UTMP *utmp_ent, time_t boottime)
+print_user (struct gl_utmp const *utmp_ent, time_t boottime)
{
struct stat stats;
time_t last_change;
@@ -434,21 +426,21 @@ print_user (const STRUCT_UTMP *utmp_ent, time_t boottime)
}
#endif
- print_line (UT_USER (utmp_ent), mesg,
+ print_line (utmp_ent->ut_user, mesg,
utmp_ent->ut_line,
time_string (utmp_ent), idlestr, pidstr,
hoststr ? hoststr : "", "");
}
static void
-print_boottime (const STRUCT_UTMP *utmp_ent)
+print_boottime (struct gl_utmp const *utmp_ent)
{
print_line ("", ' ', _("system boot"),
time_string (utmp_ent), "", "", "", "");
}
static char *
-make_id_equals_comment (STRUCT_UTMP const *utmp_ent)
+make_id_equals_comment (struct gl_utmp const *utmp_ent)
{
char const *id = UT_ID (utmp_ent);
idx_t idlen = strlen (id);
@@ -462,7 +454,7 @@ make_id_equals_comment (STRUCT_UTMP const *utmp_ent)
}
static void
-print_deadprocs (const STRUCT_UTMP *utmp_ent)
+print_deadprocs (struct gl_utmp const *utmp_ent)
{
static char *exitstr;
char *comment = make_id_equals_comment (utmp_ent);
@@ -470,12 +462,12 @@ print_deadprocs (const STRUCT_UTMP *utmp_ent)
if (!exitstr)
exitstr = xmalloc (strlen (_("term="))
- + INT_STRLEN_BOUND (UT_EXIT_E_TERMINATION (utmp_ent)) + 1
+ + INT_STRLEN_BOUND (utmp_ent->ut_exit.e_termination) + 1
+ strlen (_("exit="))
- + INT_STRLEN_BOUND (UT_EXIT_E_EXIT (utmp_ent))
+ + INT_STRLEN_BOUND (utmp_ent->ut_exit.e_exit)
+ 1);
- sprintf (exitstr, "%s%d %s%d", _("term="), UT_EXIT_E_TERMINATION (utmp_ent),
- _("exit="), UT_EXIT_E_EXIT (utmp_ent));
+ sprintf (exitstr, "%s%d %s%d", _("term="), utmp_ent->ut_exit.e_termination,
+ _("exit="), utmp_ent->ut_exit.e_exit);
/* FIXME: add idle time? */
@@ -485,7 +477,7 @@ print_deadprocs (const STRUCT_UTMP *utmp_ent)
}
static void
-print_login (const STRUCT_UTMP *utmp_ent)
+print_login (struct gl_utmp const *utmp_ent)
{
char *comment = make_id_equals_comment (utmp_ent);
PIDSTR_DECL_AND_INIT (pidstr, utmp_ent);
@@ -498,7 +490,7 @@ print_login (const STRUCT_UTMP *utmp_ent)
}
static void
-print_initspawn (const STRUCT_UTMP *utmp_ent)
+print_initspawn (struct gl_utmp const *utmp_ent)
{
char *comment = make_id_equals_comment (utmp_ent);
PIDSTR_DECL_AND_INIT (pidstr, utmp_ent);
@@ -509,7 +501,7 @@ print_initspawn (const STRUCT_UTMP *utmp_ent)
}
static void
-print_clockchange (const STRUCT_UTMP *utmp_ent)
+print_clockchange (struct gl_utmp const *utmp_ent)
{
/* FIXME: handle NEW_TIME & OLD_TIME both */
print_line ("", ' ', _("clock change"),
@@ -517,11 +509,11 @@ print_clockchange (const STRUCT_UTMP *utmp_ent)
}
static void
-print_runlevel (const STRUCT_UTMP *utmp_ent)
+print_runlevel (struct gl_utmp const *utmp_ent)
{
static char *runlevline, *comment;
- unsigned char last = UT_PID (utmp_ent) / 256;
- unsigned char curr = UT_PID (utmp_ent) % 256;
+ unsigned char last = utmp_ent->ut_pid / 256;
+ unsigned char curr = utmp_ent->ut_pid % 256;
if (!runlevline)
runlevline = xmalloc (strlen (_("run-level")) + 3);
@@ -540,7 +532,7 @@ print_runlevel (const STRUCT_UTMP *utmp_ent)
/* Print the username of each valid entry and the number of valid entries
in UTMP_BUF, which should have N elements. */
static void
-list_entries_who (idx_t n, const STRUCT_UTMP *utmp_buf)
+list_entries_who (idx_t n, struct gl_utmp const *utmp_buf)
{
idx_t entries = 0;
char const *separator = "";
@@ -572,7 +564,7 @@ print_heading (void)
/* Display UTMP_BUF, which should have N entries. */
static void
-scan_entries (idx_t n, const STRUCT_UTMP *utmp_buf)
+scan_entries (idx_t n, struct gl_utmp const *utmp_buf)
{
char *ttyname_b IF_LINT ( = nullptr);
time_t boottime = TYPE_MINIMUM (time_t);
@@ -614,7 +606,7 @@ scan_entries (idx_t n, const STRUCT_UTMP *utmp_buf)
}
if (UT_TYPE_BOOT_TIME (utmp_buf))
- boottime = UT_TIME_MEMBER (utmp_buf);
+ boottime = utmp_buf->ut_ts.tv_sec;
utmp_buf++;
}
@@ -626,8 +618,7 @@ static void
who (char const *filename, int options)
{
idx_t n_users;
- STRUCT_UTMP *utmp_buf;
-
+ struct gl_utmp *utmp_buf;
if (read_utmp (filename, &n_users, &utmp_buf, options) != 0)
error (EXIT_FAILURE, errno, "%s", quotef (filename));
--
2.39.2