GNU bug report logs - #64954
GNU 'uptime' on OpenBSD always prints "0 users"

Previous Next

Package: coreutils;

Reported by: Bruno Haible <bruno <at> clisp.org>

Date: Sun, 30 Jul 2023 14:45:01 UTC

Severity: normal

Done: Paul Eggert <eggert <at> cs.ucla.edu>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 64954 in the body.
You can then email your comments to 64954 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-coreutils <at> gnu.org:
bug#64954; Package coreutils. (Sun, 30 Jul 2023 14:45:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Bruno Haible <bruno <at> clisp.org>:
New bug report received and forwarded. Copy sent to bug-coreutils <at> gnu.org. (Sun, 30 Jul 2023 14:45:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Bruno Haible <bruno <at> clisp.org>
To: bug-coreutils <at> gnu.org
Subject: GNU 'uptime' on OpenBSD always prints "0 users"
Date: Sun, 30 Jul 2023 16:44:25 +0200
[Message part 1 (text/plain, inline)]
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.

[freebsd-13.2-config.h (text/x-chdr, attachment)]
[0001-uptime-Print-the-correct-number-of-users-on-OpenBSD.patch (text/x-patch, attachment)]

Information forwarded to bug-coreutils <at> gnu.org:
bug#64954; Package coreutils. (Sun, 30 Jul 2023 18:42:01 GMT) Full text and rfc822 format available.

Message #8 received at 64954 <at> debbugs.gnu.org (full text, mbox):

From: Pádraig Brady <P <at> draigBrady.com>
To: Bruno Haible <bruno <at> clisp.org>, 64954 <at> debbugs.gnu.org
Subject: Re: bug#64954: GNU 'uptime' on OpenBSD always prints "0 users"
Date: Sun, 30 Jul 2023 19:41:12 +0100
On 30/07/2023 15:44, Bruno Haible wrote:
> 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.

I'm fine with the change, but we'll also need to adjust
the sc_prohibit_always_true_header_tests syntax check in gnulib
as that will fail since gnulib/lib/utmp.in.h is present
and thus use of HAVE_UTMP_H is disallowed.

cheers,
Pádraig





Information forwarded to bug-coreutils <at> gnu.org:
bug#64954; Package coreutils. (Sun, 30 Jul 2023 19:44:02 GMT) Full text and rfc822 format available.

Message #11 received at 64954 <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: Pádraig Brady <P <at> draigBrady.com>
Cc: Bruno Haible <bruno <at> clisp.org>, 64954 <at> debbugs.gnu.org
Subject: Re: bug#64954: GNU 'uptime' on OpenBSD always prints "0 users"
Date: Sun, 30 Jul 2023 12:43:31 -0700
[Message part 1 (text/plain, inline)]
On 2023-07-30 11:41, Pádraig Brady wrote:
> I'm fine with the change, but we'll also need to adjust
> the sc_prohibit_always_true_header_tests syntax check in gnulib

I looked into that but it's such a hassle that I came up with the 
attached simpler patch to Coreutils. How about installing it instead? No 
Gnulib change should be needed.
[0001-uptime-output-correct-user-count-on-OpenBSD.patch (text/x-patch, attachment)]

Information forwarded to bug-coreutils <at> gnu.org:
bug#64954; Package coreutils. (Mon, 31 Jul 2023 08:39:01 GMT) Full text and rfc822 format available.

Message #14 received at 64954 <at> debbugs.gnu.org (full text, mbox):

From: Pádraig Brady <P <at> draigBrady.com>
To: Paul Eggert <eggert <at> cs.ucla.edu>
Cc: Bruno Haible <bruno <at> clisp.org>, 64954 <at> debbugs.gnu.org
Subject: Re: bug#64954: GNU 'uptime' on OpenBSD always prints "0 users"
Date: Mon, 31 Jul 2023 09:38:01 +0100
On 30/07/2023 20:43, Paul Eggert wrote:
> On 2023-07-30 11:41, Pádraig Brady wrote:
>> I'm fine with the change, but we'll also need to adjust
>> the sc_prohibit_always_true_header_tests syntax check in gnulib
> 
> I looked into that but it's such a hassle that I came up with the
> attached simpler patch to Coreutils. How about installing it instead? No
> Gnulib change should be needed.

Maybe, though I notice that gnulib docs
state the following platforms have neither getutent or getutxent,
and so might have issues with this?

OpenBSD 6.7, Minix 3.1.8, mingw, MSVC 14




Information forwarded to bug-coreutils <at> gnu.org:
bug#64954; Package coreutils. (Mon, 31 Jul 2023 09:06:01 GMT) Full text and rfc822 format available.

Message #17 received at 64954 <at> debbugs.gnu.org (full text, mbox):

From: Bruno Haible <bruno <at> clisp.org>
To: Pádraig Brady <P <at> draigbrady.com>,
 Paul Eggert <eggert <at> cs.ucla.edu>
Cc: 64954 <at> debbugs.gnu.org
Subject: Re: bug#64954: GNU 'uptime' on OpenBSD always prints "0 users"
Date: Mon, 31 Jul 2023 11:05:36 +0200
Paul Eggert wrote:
> > I'm fine with the change, but we'll also need to adjust
> > the sc_prohibit_always_true_header_tests syntax check in gnulib
> 
> I looked into that but it's such a hassle that I came up with the 
> attached simpler patch to Coreutils. How about installing it instead?

Yes, that's better than what I proposed, on two accounts:
  - Gnulib modules should better provide .h files that can be #included
    on any platform. Thus, it's Gnulib's task to provide a readutmp.h
    and a read_utmp() function that can also be used on native Windows.
  - It gets rid of the horrible hack to pass the values of two uninitialized
    variables down to a function.

Pádraig Brady wrote:
> gnulib docs
> state the following platforms have neither getutent or getutxent,
> and so might have issues with this?

OpenBSD 6.7, Minix 3.1.8, mingw, MSVC 14

On these platforms the #include "readutmp.h" would already provoke a
mass of syntax errors.

Btw, we don't test on Minix any longer (since Minix is dead),
and OpenBSD 6.x is end-of-life already [1].

Bruno

https://en.wikipedia.org/wiki/OpenBSD#Releases






Information forwarded to bug-coreutils <at> gnu.org:
bug#64954; Package coreutils. (Mon, 31 Jul 2023 14:18:01 GMT) Full text and rfc822 format available.

Message #20 received at 64954 <at> debbugs.gnu.org (full text, mbox):

From: Bruno Haible <bruno <at> clisp.org>
To: Pádraig Brady <P <at> draigbrady.com>,
 Paul Eggert <eggert <at> cs.ucla.edu>
Cc: bug-gnulib <at> gnu.org, 64954 <at> debbugs.gnu.org
Subject: Re: bug#64954: GNU 'uptime' on OpenBSD always prints "0 users"
Date: Mon, 31 Jul 2023 16:17:13 +0200
I wrote in <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=64954>:
>   - Gnulib modules should better provide .h files that can be #included
>     on any platform. Thus, it's Gnulib's task to provide a readutmp.h
>     and a read_utmp() function that can also be used on native Windows.

Done as follows:


2023-07-31  Bruno Haible  <bruno <at> clisp.org>

	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.

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 <utmp.h>
@@ -114,6 +115,24 @@
 #   endif
 #  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_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 <config.h>
 
-#if HAVE_UTMPX_H || HAVE_UTMP_H
+#include "readutmp.h"
 
-# include "readutmp.h"
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
 
-# include <stddef.h>
-# include <stdio.h>
-# include <stdlib.h>
-# include <string.h>
-# include <time.h>
+#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 <utmpx.h> nor <utmp.h> is available\n");
+      #endif
       return 77;
     }
 
@@ -99,16 +101,3 @@ main (int argc, char *argv[])
 
   return 0;
 }
-
-#else
-
-# include <stdio.h>
-
-int
-main ()
-{
-  fprintf (stderr, "Skipping test: neither <utmpx.h> nor <utmp.h> is available\n");
-  return 77;
-}
-
-#endif







Reply sent to Paul Eggert <eggert <at> cs.ucla.edu>:
You have taken responsibility. (Mon, 31 Jul 2023 16:30:02 GMT) Full text and rfc822 format available.

Notification sent to Bruno Haible <bruno <at> clisp.org>:
bug acknowledged by developer. (Mon, 31 Jul 2023 16:30:03 GMT) Full text and rfc822 format available.

Message #25 received at 64954-done <at> debbugs.gnu.org (full text, mbox):

From: Paul Eggert <eggert <at> cs.ucla.edu>
To: Bruno Haible <bruno <at> clisp.org>, Pádraig Brady
 <P <at> draigbrady.com>
Cc: 64954-done <at> debbugs.gnu.org, bug-gnulib <at> gnu.org
Subject: Re: bug#64954: GNU 'uptime' on OpenBSD always prints "0 users"
Date: Mon, 31 Jul 2023 09:29:09 -0700
Thanks, I propagated that into Coreutils and installed the simplified 
patch I mentioned yesterday. Closing the coreutils bug report.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Tue, 29 Aug 2023 11:24:08 GMT) Full text and rfc822 format available.

This bug report was last modified 1 year and 355 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.