Subject: GNU 'uptime' on OpenBSD always prints "0 users"
From: Bruno Haible <[email-masked]>
To: [email-masked]
Date: Sun, 30 Jul 2023 16:44:25 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

Hi,

GNU coreutils-9.3 'uptime', on OpenBSD 7.2, prints

 16:24:53  up 14 days 13:33,  0 users,  load average: 0.04, 0.44, 0.59

whereas the OpenBSD /usr/bin/uptime prints

 4:24PM  up 14 days, 13:33, 1 user, load averages: 0.04, 0.44, 0.59

The utmp file contain these entries:

    Time (GMT)           User          PID     Term Exit Boot User Process
------------------- --------------- ---------- ---- ---- ---- ------------
1970-01-01 00:00:00                          0   0    0            
1970-01-01 00:00:00                          0   0    0            
2023-07-16 00:52:00 bruno                    0   0    0            

The readutmp.h code, in particular the IS_USER_PROCESS macro, works fine.
(UT_TYPE_USER_PROCESS (U) expands to 0, and UT_TYPE_NOT_DEFINED expands to 1.)

The problem is that the readutmp code is entirely disabled on this platform.
Which is not appropriate.

When I revert the coreutils commit 2984e47c789ebc39f55a3b1cb20b943de88eeedc,
the coreutils 'uptime' program prints "1 user", as expected.

The rationale of that commit was wrong:
"Following gnulib commit 9041103 HAVE_UTMP_H will always be defined."
No, what that gnulib commit did is to create an <utmp.h> replacement
if the package imports the 'login_tty' module. But the HAVE_UTMP_H
is *still* only defined if the platform provides it.
Proof: On FreeBSD 13.2, which does not have <utmp.h> (it has <utmpx.h>
instead), configuring coreutils-9.3 produces the attached config.h,
which has

#define HAVE_UTMPX_H 1
/* #undef HAVE_UTMP_H */

So, find attached the fix of the bug.

From a25ec39d0a8e8fe4c2979917c89ba573315b9010 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email-masked]>
Date: Sun, 30 Jul 2023 16:30:08 +0200
Subject: [PATCH] uptime: Print the correct number of users on OpenBSD

* src/uptime.c (print_uptime, update): Revert commit 2984e47c78.
* NEWS: Mention the fix.
---
 NEWS         | 3 +++
 src/uptime.c | 4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index 92e591ee2..41205fa88 100644
--- a/NEWS
+++ b/NEWS
@@ -46,6 +46,9 @@ GNU coreutils NEWS                                    -*- outline -*-
   'pr --length=1 --double-space' no longer enters an infinite loop.
   [This bug was present in "the beginning".]
 
+  'uptime' no longer incorrectly prints "0 users" on OpenBSD.
+  [bug introduced in coreutils-9.2]
+
   'wc -l' and 'cksum' no longer crash with an "Illegal instruction" error
   on x86 Linux kernels that disable XSAVE YMM.  This was seen on Xen VMs.
   [bug introduced in coreutils-9.0]
diff --git a/src/uptime.c b/src/uptime.c
index bc31026c0..9cd92831e 100644
--- a/src/uptime.c
+++ b/src/uptime.c
@@ -100,7 +100,7 @@ print_uptime (size_t n, const STRUCT_UTMP *this)
   }
 #endif
 
-#if HAVE_STRUCT_UTMP_UT_TYPE || HAVE_STRUCT_UTMPX_UT_TYPE
+#if HAVE_UTMPX_H || HAVE_UTMP_H
   /* Loop through all the utmp entries we just read and count up the valid
      ones, also in the process possibly gleaning boottime. */
   while (n--)
@@ -177,7 +177,7 @@ uptime (char const *filename, int options)
   size_t n_users;
   STRUCT_UTMP *utmp_buf = nullptr;
 
-#if HAVE_STRUCT_UTMP_UT_TYPE || HAVE_STRUCT_UTMPX_UT_TYPE
+#if HAVE_UTMPX_H || HAVE_UTMP_H
   if (read_utmp (filename, &n_users, &utmp_buf, options) != 0)
     error (EXIT_FAILURE, errno, "%s", quotef (filename));
 #endif
-- 
2.34.1