From: Mike Yuan Date: Fri, 8 Sep 2023 18:01:57 +0000 (+0800) Subject: shared/wall: fall back to logind if utmpx database doesn't exist X-Git-Tag: v255-rc1~540^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=560f15fc8f338beb7c8a69af631db6f30507fc46;p=thirdparty%2Fsystemd.git shared/wall: fall back to logind if utmpx database doesn't exist --- diff --git a/src/shared/wall.c b/src/shared/wall.c index 9fdde59edab..d5900ef019d 100644 --- a/src/shared/wall.c +++ b/src/shared/wall.c @@ -36,18 +36,27 @@ static int write_to_terminal(const char *tty, const char *message) { return loop_write_full(fd, message, SIZE_MAX, TIMEOUT_USEC); } -#if ENABLE_UTMP static int wall_utmp( const char *message, bool (*match_tty)(const char *tty, bool is_local, void *userdata), void *userdata) { +#if ENABLE_UTMP _unused_ _cleanup_(utxent_cleanup) bool utmpx = false; struct utmpx *u; int r = 0; assert(message); + /* libc's setutxent() unfortunately doesn't inform us about success, i.e. whether /var/run/utmp + * exists. Hence we have to check manually first. */ + if (access(_PATH_UTMPX, F_OK) < 0) { + if (errno == ENOENT) + return -ENOPROTOOPT; + + return -errno; + } + utmpx = utxent_start(); while ((u = getutxent())) { @@ -77,15 +86,18 @@ static int wall_utmp( } return r; -} + +#else + return -ENOPROTOOPT; #endif +} -#if ENABLE_LOGIND static int wall_logind( const char *message, bool (*match_tty)(const char *tty, bool is_local, void *userdata), void *userdata) { +#if ENABLE_LOGIND _cleanup_strv_free_ char **sessions = NULL; int r; @@ -120,8 +132,11 @@ static int wall_logind( } return r; -} + +#else + return -ENOPROTOOPT; #endif +} int wall( const char *message, @@ -131,6 +146,7 @@ int wall( void *userdata) { _cleanup_free_ char *text = NULL, *hostname = NULL, *username_alloc = NULL, *stdin_tty = NULL; + int r; assert(message); @@ -161,11 +177,11 @@ int wall( message) < 0) return -ENOMEM; -#if ENABLE_UTMP - return wall_utmp(text, match_tty, userdata); -#elif ENABLE_LOGIND - return wall_logind(text, match_tty, userdata); -#endif + r = wall_utmp(text, match_tty, userdata); + if (r == -ENOPROTOOPT) + r = wall_logind(text, match_tty, userdata); + + return r == -ENOPROTOOPT ? 0 : r; } #endif