From nobody Sat May 09 20:44:20 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 4gCdJV20C8z6cmbt for ; Sat, 09 May 2026 20:44:26 +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 4gCdJV0zy8z3nCP for ; Sat, 09 May 2026 20:44:26 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1778359466; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=sK3mhCBS/PBNGSL5QPfcyylXhQK/S6DkHRTKnr4Kzk8=; b=GD1aqxIYZjtkR3XSOkh+EDfCJ2eMc2e90+9uADWyy/BqdoTX+E6mgFURhYao2IHchAo+9m HhVLnd32m1Rapq1UDmLOCVrszZEJdsfDGqEEKZsraApGRJC/0uYHoCTiAugTrkP1OSLpIX IGoQGDOecSTpg2tU5cpYWpaR7Ca1jJqaLXBDdxkoosPiEYYfrQpEqSf5gHK8lXqr9bP+FM HFk7vLvwHfCSVnQttIOzXezlDyDVbrzOSB5GQZ9ig1oz4C4G8A+UYWX2kcdl9nNA40sNCI mW4jPLTpr2JPbzm6BK92Eqgsv7emMQWFO5Yb3pDR9r6bbNEkoTyl7kfSiqUDTA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1778359466; a=rsa-sha256; cv=none; b=bMNgOH3AaQXU/WgkezpX+dPG+mPSAMML1pfUG3qnOctkhbq6gZ6JAO3RHsJNAXOTnzzaUg 2cqdlZg2A5+C+MH7F8WOP3QNquivJ0V0ngEK/Yc7njouIT5ypl2RpenPcu9tR4HHesooYf AswNte3KVywLT+9ZZgrdgiFPN4G/TkF0Ce2D5NnKmpplHCne00hiQ0ekrpQo9BHqbpOXbG 0fAXMcFo3TNB7enGlsrXF1G6HQY2hoZs6EjCMECcMZuYWmdMXlnJ5T1yFso3MG4WoHPwz0 hB5KSvgnPe+wCE9PCM6i/uQvp/0pfQJt3H7ZmFALkoAa9S3Ra5vXk+KW9pz/Ig== 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=1778359466; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=sK3mhCBS/PBNGSL5QPfcyylXhQK/S6DkHRTKnr4Kzk8=; b=tOZ7HvzACXP1fmO9WmXKt2TFKo83+Gfdl1f0vKD2iNTtltKrv7esuLvp/G+hKTqbf7kpfw 5VW9XTMzUu0i3di7Ylwt3F4KmhBIha6ebfV9/AMTFZEfxUSFrIechki8QVnBT+VD0Q+zjV zoGJ+zzXs98PYQlzQBeAjFZpjW12S1Vd/VpJRXRZZLB0y+BFCPph0VeD2WQL/Gg4JkA21u kCsmG/eyNqbhNB+33qHtJtqKecvFqGLaGhYHC0cyNGmTzBevDmD9+MYBf38grJHUpuEd1Z 2uzxm00KPQPfstyPrOxbGzoXSlKj8uKkLjRrl+giqz+AZW34yIcF8sQeU6FTcw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4gCdJT6cbFz1F8h for ; Sat, 09 May 2026 20:44:25 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 23ffe by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sat, 09 May 2026 20:44:20 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Cc: Mark Johnston From: Colin Percival Subject: git: 037b285b80e5 - releng/15.1 - unix: Make sure we signal EOF on the write side when disconnecting 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: cperciva X-Git-Repository: src X-Git-Refname: refs/heads/releng/15.1 X-Git-Reftype: branch X-Git-Commit: 037b285b80e5cb35c8e9cec4e85966b20f03d91a Auto-Submitted: auto-generated Date: Sat, 09 May 2026 20:44:20 +0000 Message-Id: <69ff9ca4.23ffe.55918be4@gitrepo.freebsd.org> The branch releng/15.1 has been updated by cperciva: URL: https://cgit.FreeBSD.org/src/commit/?id=037b285b80e5cb35c8e9cec4e85966b20f03d91a commit 037b285b80e5cb35c8e9cec4e85966b20f03d91a Author: Mark Johnston AuthorDate: 2026-05-03 15:46:22 +0000 Commit: Colin Percival CommitDate: 2026-05-09 20:44:04 +0000 unix: Make sure we signal EOF on the write side when disconnecting Add a regression test. Approved by: re (cperciva) PR: 294014 Reported by: diizzy Reviewed by: glebius MFC after: 1 week Fixes: d15792780760 ("unix: new implementation of unix/stream & unix/seqpacket") Differential Revision: https://reviews.freebsd.org/D56764 (cherry picked from commit 476805133f5736c2c8638e41d2b5d8dd2c597f3a) (cherry picked from commit f06697907f360b02682594c6179a7361644d3c87) --- sys/kern/uipc_usrreq.c | 2 ++ tests/sys/kern/unix_stream.c | 77 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 62 insertions(+), 17 deletions(-) diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 6569422a3710..44d0185e9d1c 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -3162,6 +3162,8 @@ unp_soisdisconnected(struct socket *so) so->so_state |= SS_ISDISCONNECTED; so->so_state &= ~SS_ISCONNECTED; so->so_rcv.uxst_peer = NULL; + selwakeuppri(&so->so_wrsel, PSOCK); + KNOTE_LOCKED(&so->so_snd.sb_sel->si_note, 0); socantrcvmore_locked(so); } diff --git a/tests/sys/kern/unix_stream.c b/tests/sys/kern/unix_stream.c index 442b766ac885..df8dd1a15f85 100644 --- a/tests/sys/kern/unix_stream.c +++ b/tests/sys/kern/unix_stream.c @@ -109,6 +109,7 @@ typedef void check_func_t(struct check_ctx *); struct check_ctx { check_func_t *method; int sv[2]; + int kq; bool timeout; union { enum { SELECT_RD, SELECT_WR } select_what; @@ -156,24 +157,47 @@ check_poll(struct check_ctx *ctx) } static void -check_kevent(struct check_ctx *ctx) +add_kevent(struct check_ctx *ctx) { struct kevent kev; - int nfds, kq; + int kq, nfds; + + if (ctx->kq <= 0) { + kq = kqueue(); + ATF_REQUIRE(kq > 0); + ctx->kq = kq; + } - ATF_REQUIRE(kq = kqueue()); EV_SET(&kev, ctx->sv[0], ctx->kev_filter, EV_ADD, 0, 0, NULL); - nfds = kevent(kq, &kev, 1, NULL, 0, NULL); + nfds = kevent(ctx->kq, &kev, 1, NULL, 0, NULL); ATF_REQUIRE_MSG(nfds == 0, "kevent() returns %d errno %d", nfds, errno); - nfds = kevent(kq, NULL, 0, &kev, 1, ctx->timeout ? +} + +static void +check_kevent(struct check_ctx *ctx) +{ + struct kevent kev; + int nfds; + + nfds = kevent(ctx->kq, NULL, 0, &kev, 1, ctx->timeout ? &(struct timespec){.tv_nsec = 1000000} : NULL); ATF_REQUIRE_MSG(nfds == ctx->nfds, "kevent() returns %d errno %d", nfds, errno); - ATF_REQUIRE(kev.ident == (uintptr_t)ctx->sv[0] && - kev.filter == ctx->kev_filter && - (kev.flags & ctx->kev_flags) == ctx->kev_flags); - close(kq); + if (nfds > 0) { + ATF_REQUIRE_EQ(kev.ident, (uintptr_t)ctx->sv[0]); + ATF_REQUIRE_EQ(kev.filter, ctx->kev_filter); + ATF_REQUIRE_EQ(kev.flags & ctx->kev_flags, ctx->kev_flags); + } + close(ctx->kq); + ctx->kq = -1; +} + +static void +add_and_check_kevent(struct check_ctx *ctx) +{ + add_kevent(ctx); + check_kevent(ctx); } static void @@ -287,7 +311,7 @@ ATF_TC_WITHOUT_HEAD(full_writability_kevent); ATF_TC_BODY(full_writability_kevent, tc) { struct check_ctx ctx = { - .method = check_kevent, + .method = add_and_check_kevent, .kev_filter = EVFILT_WRITE, }; @@ -312,7 +336,7 @@ ATF_TC_BODY(connected_writability, tc) ctx.poll_events = POLLOUT | POLLWRNORM; check_poll(&ctx); ctx.kev_filter = EVFILT_WRITE; - check_kevent(&ctx); + add_and_check_kevent(&ctx); close(ctx.sv[0]); close(ctx.sv[1]); @@ -333,13 +357,13 @@ ATF_TC_BODY(unconnected_writability, tc) ctx.poll_events = POLLOUT | POLLWRNORM; check_poll(&ctx); ctx.kev_filter = EVFILT_WRITE; - check_kevent(&ctx); + add_and_check_kevent(&ctx); close(ctx.sv[0]); } -ATF_TC_WITHOUT_HEAD(peerclosed_writability); -ATF_TC_BODY(peerclosed_writability, tc) +ATF_TC_WITHOUT_HEAD(peerclosed_writability_level); +ATF_TC_BODY(peerclosed_writability_level, tc) { struct check_ctx ctx = { .timeout = false, @@ -355,6 +379,24 @@ ATF_TC_BODY(peerclosed_writability, tc) check_poll(&ctx); ctx.kev_filter = EVFILT_WRITE; ctx.kev_flags = EV_EOF; + add_and_check_kevent(&ctx); + + close(ctx.sv[0]); +} + +ATF_TC_WITHOUT_HEAD(peerclosed_writability_edge); +ATF_TC_BODY(peerclosed_writability_edge, tc) +{ + struct check_ctx ctx = { + .timeout = false, + .nfds = 1, + }; + + do_socketpair(ctx.sv); + ctx.kev_filter = EVFILT_WRITE; + ctx.kev_flags = EV_EOF; + add_kevent(&ctx); + close(ctx.sv[1]); check_kevent(&ctx); close(ctx.sv[0]); @@ -384,7 +426,7 @@ ATF_TC_BODY(peershutdown_writability, tc) * and then this test will also expect EV_EOF in returned flags. */ ctx.kev_filter = EVFILT_WRITE; - check_kevent(&ctx); + add_and_check_kevent(&ctx); close(ctx.sv[0]); close(ctx.sv[1]); @@ -463,7 +505,7 @@ ATF_TC_WITHOUT_HEAD(peershutdown_wakeup_kevent); ATF_TC_BODY(peershutdown_wakeup_kevent, tc) { peershutdown_wakeup(&(struct check_ctx){ - .method = check_kevent, + .method = add_and_check_kevent, .kev_filter = EVFILT_READ, .kev_flags = EV_EOF, }); @@ -525,7 +567,8 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, full_writability_select); ATF_TP_ADD_TC(tp, full_writability_poll); ATF_TP_ADD_TC(tp, full_writability_kevent); - ATF_TP_ADD_TC(tp, peerclosed_writability); + ATF_TP_ADD_TC(tp, peerclosed_writability_level); + ATF_TP_ADD_TC(tp, peerclosed_writability_edge); ATF_TP_ADD_TC(tp, peershutdown_writability); ATF_TP_ADD_TC(tp, peershutdown_readability); ATF_TP_ADD_TC(tp, peershutdown_wakeup_select);