From nobody Thu May 28 08:03:04 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4gQzWD4T87z6fJJD for ; Thu, 28 May 2026 08:03:04 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R13" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4gQzWD2BPtz3mSF for ; Thu, 28 May 2026 08:03:04 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1779955384; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Cw4brEz1WuXwPB2t7WTbQCbWmg5R1m7z0De0lfwG0NM=; b=jwPkytznVznTUZMa4m96IKi1Kyog4QSMsOTgY6USKZc0AcvCWHy3WvpFnZTaU/q/X51IFC 19pgzxwpBh8Ri7z2T3v147/zDc3SMSaQCHoqrTQzRvzcrdYWyGIBar49Zf7v53c3fTbQbb 70nQoO0uBV5US0dJQ3xMeuXuDi8A+2SmIa4npcmE6zPBsvVKxeVzreOenJoBeT3j2njLxY lFxgJfPbigZjZ18aKEEVJh0g4PzZLL2Wp1CTgcmo1dee1e6qpIEargmlpAOd3p8WlQ4gwX 4sPEFrbowtIYH3vCbWoE1dv6QmAsYfmm3/jHS6xkFlgThDVAsWrQrDcn3yFlIQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1779955384; a=rsa-sha256; cv=none; b=qaEdi9mRsL8CCbQ7MBB5x575ai73e1NQgRN4RENd9ZdynHxTcGcyIsCLd9uDLWKb+Pm3iJ Z7wqXGpznjptrW286m95xweTVVlVq5ClLAiG2FeuyhposC5ZxcBjM7KlNYl7XaJNOjidnv hI9f/l/nsjrSX+wEbe29ioVa1D/RR83sev9yTJiZoZk2Qk4/XgVqXoSA3gzQPianQXaiTK 4QfIA+J2qDUoF1J63Qn4Ls1mPJ1fhErRCu+L69HTYwcEHpoXp0piT1UbxadxgZFiJVD7hc iT9SXAS4BjtNIosklruX2AFO8Zm7IU38W5WbxBMuF4uPMWw2xUH8SqI6bsX7Gw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1779955384; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Cw4brEz1WuXwPB2t7WTbQCbWmg5R1m7z0De0lfwG0NM=; b=mu2E6K1XcLa5DFV0H4DB5hngC9U3Likkzpud+7xc022rfVWetugWcbZykLEbFjQJfhZIZ3 4TJ39wI67kvt2Ic/WR1ZZ6x7JhsBXTx1z0MC+1FTg74fpkWV5PNWGXZy8Y+lJhPN4mx7Zo xSdhXJSSvyy6U2lDV/whryQOYQStseen/CJuxgcv8o2XxUBu1l/XarNEM8fvzyniEX8qjW b1oNOdiKW4Q8teLDos417OfxCs9mkVP1eS4PgIEkgqigqPOYRjngwErvu6pfunr9okSfI4 4t9EThTt0VeQ8QCBhWfigveL1F/LBuVMMt6I+iXMs5LoJkAPM7Q2SFRF8Ub5oQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gQzWD1kmhzdq8 for ; Thu, 28 May 2026 08:03:04 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 21b11 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Thu, 28 May 2026 08:03:04 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Dag-Erling=?utf-8?Q? Sm=C3=B8rg?=rav Subject: git: 3d6c7334c73e - stable/14 - ttymsg: Overhaul List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: des X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 3d6c7334c73ee459feb57dcd8bc350f5f6308b41 Auto-Submitted: auto-generated Date: Thu, 28 May 2026 08:03:04 +0000 Message-Id: <6a17f6b8.21b11.bb4a95c@gitrepo.freebsd.org> The branch stable/14 has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=3d6c7334c73ee459feb57dcd8bc350f5f6308b41 commit 3d6c7334c73ee459feb57dcd8bc350f5f6308b41 Author: Dag-Erling Smørgrav AuthorDate: 2026-05-25 16:51:23 +0000 Commit: Dag-Erling Smørgrav CommitDate: 2026-05-28 08:02:52 +0000 ttymsg: Overhaul * Instead of an error string, return the usual 0 or -1 and let the caller figure out what, if anything, to tell the user. * Avoid string manipulations by opening /dev first and using openat() with O_RESOLVE_BENEATH. * Add a boolean argument which, if false, causes ttymsg() to return without sending the message if the tty's group-writable bit is not set. This saves programs that respect this setting (like syslogd(8)) from having to check before calling ttymsg(). * Update all callers. The observable effect of this change is minimal except for slightly different error messages when ttymsg() fails. However, syslogd(8) will no longer print spurious error messages on the console after trying and failing to write a log message to an X11 session. PR: 295171 MFC after: 1 week Reviewed by: jfree, markj Differential Revision: https://reviews.freebsd.org/D57018 (cherry picked from commit 05e8f2bf0906875e666469e0338f922d1113d034) --- libexec/talkd/announce.c | 3 +- usr.bin/wall/ttymsg.c | 118 ++++++++++++++++++++++++--------------------- usr.bin/wall/ttymsg.h | 2 +- usr.bin/wall/wall.c | 6 +-- usr.sbin/syslogd/syslogd.c | 48 ++++-------------- 5 files changed, 79 insertions(+), 98 deletions(-) diff --git a/libexec/talkd/announce.c b/libexec/talkd/announce.c index b1b1acc09553..71e4342c6068 100644 --- a/libexec/talkd/announce.c +++ b/libexec/talkd/announce.c @@ -46,6 +46,7 @@ static char sccsid[] = "@(#)announce.c 8.3 (Berkeley) 4/28/95"; #include #include +#include #include #include #include @@ -158,7 +159,7 @@ print_mesg(const char *tty, CTL_MSG *request, * stack up processes trying to write messages to a tty * that is permanently blocked. */ - if (ttymsg(&iovec, 1, tty, RING_WAIT - 5) != NULL) + if (ttymsg(&iovec, 1, tty, RING_WAIT - 5, true) != 0) return (FAILED); return (SUCCESS); diff --git a/usr.bin/wall/ttymsg.c b/usr.bin/wall/ttymsg.c index dc149db84885..5f57f7b00509 100644 --- a/usr.bin/wall/ttymsg.c +++ b/usr.bin/wall/ttymsg.c @@ -35,12 +35,15 @@ static const char sccsid[] = "@(#)ttymsg.c 8.2 (Berkeley) 11/16/93"; #endif #include +#include #include + #include #include #include #include #include +#include #include #include #include @@ -49,65 +52,72 @@ static const char sccsid[] = "@(#)ttymsg.c 8.2 (Berkeley) 11/16/93"; #include "ttymsg.h" /* - * Display the contents of a uio structure on a terminal. Used by wall(1), - * syslogd(8), and talkd(8). Forks and finishes in child if write would block, - * waiting up to tmout seconds. Returns pointer to error string on unexpected - * error; string is not newline-terminated. Various "normal" errors are - * ignored (exclusive-use, lack of permission, etc.). + * Display the contents of a uio structure on a terminal. If shout is + * non-zero, do so even if the terminal has messages disabled. Used by + * wall(1), syslogd(8), and talkd(8). Forks and finishes in child if + * write would block, waiting up to timeout seconds. Various "normal" + * errors are ignored (exclusive-use, lack of permission, etc.). */ -const char * -ttymsg(struct iovec *iov, int iovcnt, const char *line, int tmout) +int +ttymsg(struct iovec *iov, int iovcnt, const char *tty, int timeout, + bool shout) { struct iovec localiov[TTYMSG_IOV_MAX]; - ssize_t left, wret; - int cnt, fd; - char device[MAXNAMLEN] = _PATH_DEV; - static char errbuf[1024]; - char *p; + struct stat sb; + ssize_t wret; + size_t resid; + int cnt, dd, fd, serrno; int forked; forked = 0; - if (iovcnt > (int)(sizeof(localiov) / sizeof(localiov[0]))) - return ("too many iov's (change code in wall/ttymsg.c)"); - - strlcat(device, line, sizeof(device)); - p = device + sizeof(_PATH_DEV) - 1; - if (strncmp(p, "pts/", 4) == 0) - p += 4; - if (strchr(p, '/') != NULL) { - /* A slash is an attempt to break security... */ - (void) snprintf(errbuf, sizeof(errbuf), - "Too many '/' in \"%s\"", device); - return (errbuf); + if (iovcnt > (int)(sizeof(localiov) / sizeof(localiov[0]))) { + errno = EFBIG; + return (-1); } - /* - * open will fail on slip lines or exclusive-use lines - * if not running as root; not an error. - */ - if ((fd = open(device, O_WRONLY|O_NONBLOCK, 0)) < 0) { - if (errno == EBUSY || errno == EACCES) - return (NULL); - (void) snprintf(errbuf, sizeof(errbuf), "%s: %s", device, - strerror(errno)); - return (errbuf); + dd = open(_PATH_DEV, O_SEARCH | O_DIRECTORY); + if (dd < 0) + return (-1); + fd = openat(dd, tty, O_WRONLY | O_NONBLOCK | O_RESOLVE_BENEATH); + if (fd < 0) { + serrno = errno; + close(dd); + /* + * open will fail on slip lines or exclusive-use lines + * if not running as root; not an error. + */ + if (serrno == EBUSY || serrno == EACCES) + return (0); + errno = serrno; + return (-1); + } + close(dd); + if (!shout) { + if (fstat(fd, &sb) != 0) { + serrno = errno; + close(fd); + errno = serrno; + return (-1); + } + if ((sb.st_mode & S_IWGRP) == 0) { + close(fd); + return (0); + } } - for (cnt = 0, left = 0; cnt < iovcnt; ++cnt) - left += iov[cnt].iov_len; + for (cnt = 0, resid = 0; cnt < iovcnt; ++cnt) + resid += iov[cnt].iov_len; - for (;;) { + do { wret = writev(fd, iov, iovcnt); - if (wret >= left) - break; if (wret >= 0) { - left -= wret; + resid -= wret; if (iov != localiov) { - bcopy(iov, localiov, + bcopy(iov, localiov, iovcnt * sizeof(struct iovec)); iov = localiov; } - for (cnt = 0; (size_t)wret >= iov->iov_len; ++cnt) { + while ((size_t)wret >= iov->iov_len) { wret -= iov->iov_len; ++iov; --iovcnt; @@ -127,21 +137,21 @@ ttymsg(struct iovec *iov, int iovcnt, const char *line, int tmout) } cpid = fork(); if (cpid < 0) { - (void) snprintf(errbuf, sizeof(errbuf), - "fork: %s", strerror(errno)); + serrno = errno; (void) close(fd); - return (errbuf); + errno = serrno; + return (-1); } if (cpid) { /* parent */ (void) close(fd); - return (NULL); + return (0); } forked++; - /* wait at most tmout seconds */ + /* wait at most timeout seconds */ (void) signal(SIGALRM, SIG_DFL); (void) signal(SIGTERM, SIG_DFL); /* XXX */ (void) sigsetmask(0); - (void) alarm((u_int)tmout); + (void) alarm((u_int)timeout); (void) fcntl(fd, F_SETFL, 0); /* clear O_NONBLOCK */ continue; } @@ -149,18 +159,18 @@ ttymsg(struct iovec *iov, int iovcnt, const char *line, int tmout) * We get ENODEV on a slip line if we're running as root, * and EIO if the line just went away. */ - if (errno == ENODEV || errno == EIO) + serrno = errno; + if (serrno == ENODEV || serrno == EIO) break; (void) close(fd); if (forked) _exit(1); - (void) snprintf(errbuf, sizeof(errbuf), - "%s: %s", device, strerror(errno)); - return (errbuf); - } + errno = serrno; + return (-1); + } while (resid > 0); (void) close(fd); if (forked) _exit(0); - return (NULL); + return (0); } diff --git a/usr.bin/wall/ttymsg.h b/usr.bin/wall/ttymsg.h index be97592f5e1c..840a49875fbb 100644 --- a/usr.bin/wall/ttymsg.h +++ b/usr.bin/wall/ttymsg.h @@ -1,4 +1,4 @@ #define TTYMSG_IOV_MAX 32 -const char *ttymsg(struct iovec *, int, const char *, int); +int ttymsg(struct iovec *, int, const char *, int, bool); diff --git a/usr.bin/wall/wall.c b/usr.bin/wall/wall.c index 335f83623576..c75b7a71bf0a 100644 --- a/usr.bin/wall/wall.c +++ b/usr.bin/wall/wall.c @@ -55,6 +55,7 @@ static const char sccsid[] = "@(#)wall.c 8.2 (Berkeley) 11/16/93"; #include #include #include +#include #include #include #include @@ -101,7 +102,6 @@ main(int argc, char *argv[]) struct wallgroup *g; struct group *grp; char **np; - const char *p; struct passwd *pw; (void)setlocale(LC_CTYPE, ""); @@ -169,8 +169,8 @@ main(int argc, char *argv[]) if (ingroup == 0) continue; } - if ((p = ttymsg(&iov, 1, utmp->ut_line, 60*5)) != NULL) - warnx("%s", p); + if (ttymsg(&iov, 1, utmp->ut_line, 60 * 5, 1) != 0) + warn("%s", utmp->ut_line); } exit(0); } diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c index be12e8db7b85..fc4afe3161f5 100644 --- a/usr.sbin/syslogd/syslogd.c +++ b/usr.sbin/syslogd/syslogd.c @@ -449,7 +449,6 @@ static void parsemsg(const char *, char *); static void printsys(char *); static int p_open(const char *, pid_t *); static void reapchild(int); -static const char *ttymsg_check(struct iovec *, int, char *, int); static void usage(void); static int validate(struct sockaddr *, const char *); static void unmapped(struct sockaddr *); @@ -1836,7 +1835,6 @@ fprintlog_write(struct filed *f, struct iovlist *il, int flags) struct msghdr msghdr; struct addrinfo *r; struct socklist *sl; - const char *msgret; ssize_t lsent; switch (f->f_type) { @@ -1966,9 +1964,9 @@ fprintlog_write(struct filed *f, struct iovlist *il, int flags) dprintf(" %s%s\n", _PATH_DEV, f->fu_fname); iovlist_append(il, "\r\n"); errno = 0; /* ttymsg() only sometimes returns an errno */ - if ((msgret = ttymsg(il->iov, il->iovcnt, f->fu_fname, 10))) { + if (ttymsg(il->iov, il->iovcnt, f->fu_fname, 10, true) != 0) { f->f_type = F_UNUSED; - logerror(msgret); + logerror(f->fu_fname); } break; @@ -2190,7 +2188,6 @@ wallmsg(struct filed *f, struct iovec *iov, const int iovlen) static int reenter; /* avoid calling ourselves */ struct utmpx *ut; int i; - const char *p; if (reenter++) return; @@ -2200,23 +2197,19 @@ wallmsg(struct filed *f, struct iovec *iov, const int iovlen) if (ut->ut_type != USER_PROCESS) continue; if (f->f_type == F_WALL) { - if ((p = ttymsg(iov, iovlen, ut->ut_line, - TTYMSGTIME)) != NULL) { - errno = 0; /* already in msg */ - logerror(p); - } + if (ttymsg(iov, iovlen, ut->ut_line, TTYMSGTIME, + false) != 0 && errno != ENOENT) + dprintf("%s: %m\n", ut->ut_line); continue; } /* should we send the message to this user? */ for (i = 0; i < MAXUNAMES; i++) { if (!f->fu_uname[i][0]) break; - if (!strcmp(f->fu_uname[i], ut->ut_user)) { - if ((p = ttymsg_check(iov, iovlen, ut->ut_line, - TTYMSGTIME)) != NULL) { - errno = 0; /* already in msg */ - logerror(p); - } + if (strcmp(f->fu_uname[i], ut->ut_user) == 0) { + if (ttymsg(iov, iovlen, ut->ut_line, TTYMSGTIME, + true) != 0 && errno != ENOENT) + dprintf("%s: %m\n", ut->ut_line); break; } } @@ -2225,29 +2218,6 @@ wallmsg(struct filed *f, struct iovec *iov, const int iovlen) reenter = 0; } -/* - * Wrapper routine for ttymsg() that checks the terminal for messages enabled. - */ -static const char * -ttymsg_check(struct iovec *iov, int iovcnt, char *line, int tmout) -{ - static char device[1024]; - static char errbuf[1024]; - struct stat sb; - - (void) snprintf(device, sizeof(device), "%s%s", _PATH_DEV, line); - - if (stat(device, &sb) < 0) { - (void) snprintf(errbuf, sizeof(errbuf), - "%s: %s", device, strerror(errno)); - return (errbuf); - } - if ((sb.st_mode & S_IWGRP) == 0) - /* Messages disabled. */ - return (NULL); - return ttymsg(iov, iovcnt, line, tmout); -} - static void reapchild(int signo __unused) {