From nobody Sun May 3 23:09:19 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 4g80pX3vj8z6cLFH for ; Sun, 03 May 2026 23:09:24 +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 4g80pX1hlyz3Xnd for ; Sun, 03 May 2026 23:09:24 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1777849764; 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=NLNf9g69INEu6DZ6geNUWhMdl0bK2ZZgdFbC56RK2AI=; b=HM0Z5AaCDnKwdSLHJnVPT4eRK3d0yLqPcLsRrSIuEcWcd4aRNZm6Evdl+bDpVrjEN2L+WY 7mCo4G/UIZWQ3dlWtGq5TjFFHVVnP8OySl9K8cClNDqSmCUhu7kYvvkNdG6EX8uvgZxKHB umxyJVemDW1e6odB10V4VQE7iH9dJKskWWwS5o53cZOr9GdwdxVozuLJhRFwvryI4PFWa2 TcAD3QpscZbrGDSMw/By6H/qflpMpskvCCl7KLmmDvw+K9OHpA3wCO8NiwvKge240Yj8k1 J9pgFHw3Zhu7PbWXbklPgpCZt9I7H+aFFLGXMH5J7HaJVw4yfl9KJxENNzBwJg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1777849764; a=rsa-sha256; cv=none; b=g577SX8JQYrgGsVVFEjR0TY1udFXJdxg4DyQ0yq//LyMk29hOyaXDxqG/UI/Jgs3rPTLEq epIgaI33X3lXSLqTIMvBhMtONMnjHlDeY6vQvI6pZKn4mv10NFJuM2Blgc4oIWcvmTgkZx luWoOVmWU0ArhHl6evwAAErznfOb8WVgzBkaLVAW+N5DSmciPxMXz+UA5Gf8B6TEh7MFOU XeMHMeWgTqw/thqIUYioUL0sKnlgtgGfFXokPEby7GDsCmy8WFvV1VC3ay8Uj5CP4uXUjg bxTr6oEn8u0rYeH218qAqyPfcLz/a3hLtrrJkXRUDW0rC4rpdoyoqkjDz0fd5Q== 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=1777849764; 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=NLNf9g69INEu6DZ6geNUWhMdl0bK2ZZgdFbC56RK2AI=; b=flsVTjzZL0nP5FKlZEb+nFyVbCvktZEcFipUX0KdiZDnU/eYbFOpHRtIiCar0m/dM8y6Jr yuiVbURic93WyW4H69+5RqqQipJGqziATJ4kkEHhc9UfmI3QTrBN1Uoxhg1yZUht6gc0+J jYB83inye9TV8pN74EYrNeY/kWXLu8qI7+fdXpF51HjAUyg8WJiqUuJcO5Kv4+F4zvpPNh rXGscm8pzFG1OjVT3EmxynhgVAZFVSU8d22cRurBTAAPG4z2juJUuizHLz5gZkTLOWs5bz WCz3w4U/d/kCqgLrxb6jk46cuGp36sTw11NwWkofT1UEVW0XzVIP1pkH8nzvmQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4g80pX1JSTztDM for ; Sun, 03 May 2026 23:09:24 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 24c32 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 03 May 2026 23:09:19 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mark Johnston Subject: git: 476805133f57 - main - 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: markj X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 476805133f5736c2c8638e41d2b5d8dd2c597f3a Auto-Submitted: auto-generated Date: Sun, 03 May 2026 23:09:19 +0000 Message-Id: <69f7d59f.24c32.3cabcabf@gitrepo.freebsd.org> The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=476805133f5736c2c8638e41d2b5d8dd2c597f3a commit 476805133f5736c2c8638e41d2b5d8dd2c597f3a Author: Mark Johnston AuthorDate: 2026-05-03 15:46:22 +0000 Commit: Mark Johnston CommitDate: 2026-05-03 21:51:49 +0000 unix: Make sure we signal EOF on the write side when disconnecting Add a regression test. 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 --- 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 d56aac883d9c..8ff9822ee9eb 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -3159,6 +3159,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);