syslod, talkd: GNU/Linux w/o utmp compatibility

Some newer GNU/Linux systems no longer have a "utmp" file.
This file is used by both syslogd and talkd to find the
TTY device files of active user sessions in order to send
messages to specific or all users.

Gnulib can emulate a utmp file via the read_utmp() function
from the readutmp module.  This emulation is activated by
defining "READUTMP_USE_SYSTEMD", triggered via configure's
"--enable-systemd" option on systems without utmp and with
systemd.

But, this emulation reports non-existing TTY device files
for active user sessions.  Attempting to send a message to a
non-existing TTY produces an error, but that is normal behavior
for such a system.  Thus, ignore this error on such systems,
but not others.

* NEWS.md: Mention enhancement.
* libinetutils/ttymsg.c (inetutils_ttymsg): Ignore errors for
  non-existings TTY files reported in emulated utmp entries.
This commit is contained in:
Erik Auerswald
2025-12-03 21:24:22 +01:00
parent 5fbd8cb999
commit 0c9d12e0da
2 changed files with 17 additions and 0 deletions

View File

@@ -16,6 +16,12 @@ Thanks to Benjamin Cathelineau, see
** Fix codespell typos.
** syslogd, talkd: Better compatibility with utmp-less GNU/Linux systems
when configuring with --enable-systemd.
Thanks to Valentin Haudiquet for reporting the issue and testing possible
solutions. For more info, see the thread starting at
<https://lists.gnu.org/archive/html/bug-inetutils/2025-11/msg00000.html>.
# Noteworthy changes in release 2.6 (2025-02-21) [stable]
** The release tarball is now reproducible.

View File

@@ -109,6 +109,17 @@ inetutils_ttymsg (struct iovec *iov, int iovcnt, char *line, int tmout)
{
if (errno == EBUSY || errno == EACCES)
return (NULL);
#ifdef READUTMP_USE_SYSTEMD
/*
* GNU/Linux systems without utmp file but with utmp emulation
* provided via Gnulib's read_utmp() function regularly return
* non-existing TTYs for some active user sessions. This is a
* limitation of the utmp emulation. Thus ignore this error on
* such systems, but not others.
*/
if (errno == ENOENT)
return (NULL);
#endif
snprintf (errbuf, sizeof (errbuf), "%s: %s", device, strerror (errno));
free (device);
return errbuf;