From nobody Sun May 3 23:09:19 2026 X-Original-To: dev-commits-src-main@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 4g80pR4Frxz6cLCB for ; Sun, 03 May 2026 23:09:19 +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 4g80pR20jqz3Y9b for ; Sun, 03 May 2026 23:09:19 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1777849759; 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=PSAJnrZR/+6HJsI0QYQTUKKZVWvSJz0/0RuFLgyRorzKYsJQWNgX1KH/jCaIa1G6GPDLOk gcBh5HUklH00wgDPMAeGAU2vDfBdx5A8iiEB2oE3Ifd7+XHy9KPdEFMhl+Xvq0sHn7UNXs C0Ui/GhF7zkJDplOdQGbTXLK7j30VxldTVLNxrWejzHG7phH1UIwgsyYkoObiawV4YZqSm et+6Ek6nd4IsQD277SkNgFMrz54pw7ZiUSDDCNmOe0LtQROKKiUZpsRHJRfcCDU8xrcQSc 5wNq0vYS2cWUUgyp0lAUHIAJYVqvrL+E5lfJ4uORLu+RU3GOK1bXiER9QzLJQA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1777849759; a=rsa-sha256; cv=none; b=jl0VQF6Uc4niblFgyAy3U4tS2Ewbh2cVfP6FJQEJSyZF2kY3FQ/3sHceNPBTIabiTj8WZf Udw0+nKeorsfDHJMpOzdG2ftvv7a/vhQupvRwTqoxI/oKvFZ65VLJHs4aet7rUGhBw2Hjv LdGJoL+jBq5kHIp5AYH2UtuglfAXLJgv4ylw2UJEYnSq+qifvHPZWHsFZxKg5YgJRtpDEZ Fb7jFLQ/CSrDBVUD4ZRflotLSWdhevPU20rIXNiyJ4hOcWgy1Tv77mklrnaPuEmPPQIPay PFaB+W0/bnX0PSMbCIRRTPnsa9AX39Aej1ED+0+1gT+7g4Gl/E1gdhvKbz27iA== 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=1777849759; 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=M9u/5xtlj1ZCBRToULL1neu+hv9qHA7Jsi/FvyZ80Xx92rJ/Jm4ai8SSxa9CkSsOBceqwP hTxq0t0SAi0S8spkkioT2aIzOcQhfGRha+YcM9+NQ0O7o8zTkZkIhRM23U7mBxNmie2NRx WcJOJBtTrjZpgqzHKxxnXacfgqaG464toS43/T+1ZkrmqP5kOn6/Uui+PadIJojVluP7i/ 7InPZmnv/sayjOzT6pdxWQLVwxLPHEDRZHuH82bqUhq5S/pMXDS+7bQoP2kpmiDwxckvGY 9nx2uio4J/ThNJ6tlB2Aw6LXTxmLz5GlkysyN7n9+Ga2z40FP0Z40ZSwuVTtNw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4g80pR1KTQztgh for ; Sun, 03 May 2026 23:09:19 +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 the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@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);