git: 60d5a4216b34 - main - unix/stream: fix EVFILT_WRITE after we did shutdown(2)
Date: Tue, 02 Sep 2025 20:34:22 UTC
The branch main has been updated by glebius:
URL: https://cgit.FreeBSD.org/src/commit/?id=60d5a4216b3479a2d62eb65f2cb03b799546dcbb
commit 60d5a4216b3479a2d62eb65f2cb03b799546dcbb
Author: Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2025-09-02 20:34:12 +0000
Commit: Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2025-09-02 20:34:12 +0000
unix/stream: fix EVFILT_WRITE after we did shutdown(2)
When fixing bug 286692, the change eafe5967ac558, that fixed a case when
peer side does close(), also had regressed a case when our side does
shutdown(SHUT_WR). These actually are two independent code paths, and the
eafe5967ac558 shouldn't have touched the second block. The removal of
'kn->kn_flags |= EV_EOF' was incorrect and the statement on original
behavior in the commit message was also incorrect.
Do not add back so_error setting, since I failed to find a test case that
would return anything but 0 in kevent.fflags when run on stable/14.
This was found with help of https://github.com/tokio-rs/mio. Add a test
case into our test suite for that.
Fixes: eafe5967ac558de142d91660e18e9238289890e3
Reviewed by: markj
Differential Revision: https://reviews.freebsd.org/D52327
---
sys/kern/uipc_usrreq.c | 4 +---
tests/sys/kern/unix_stream.c | 24 ++++++++++++++++++++++++
2 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index 19870e989437..6138e543fae7 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -1807,9 +1807,7 @@ uipc_filt_sowrite(struct knote *kn, long hint)
kn->kn_data = uipc_stream_sbspace(&so2->so_rcv);
if (so2->so_rcv.sb_state & SBS_CANTRCVMORE) {
- /*
- * XXXGL: maybe kn->kn_flags |= EV_EOF ?
- */
+ kn->kn_flags |= EV_EOF;
return (1);
} else if (kn->kn_sfflags & NOTE_LOWAT)
return (kn->kn_data >= kn->kn_sdata);
diff --git a/tests/sys/kern/unix_stream.c b/tests/sys/kern/unix_stream.c
index bb811f78f620..49d621dc5b0a 100644
--- a/tests/sys/kern/unix_stream.c
+++ b/tests/sys/kern/unix_stream.c
@@ -467,6 +467,29 @@ ATF_TC_BODY(peershutdown_wakeup_kevent, tc)
});
}
+ATF_TC_WITHOUT_HEAD(ourshutdown_kevent);
+ATF_TC_BODY(ourshutdown_kevent, tc)
+{
+ struct kevent kev;
+ int sv[2], kq;
+
+ do_socketpair(sv);
+ ATF_REQUIRE(kq = kqueue());
+
+ EV_SET(&kev, sv[1], EVFILT_WRITE, EV_ADD, 0, 0, NULL);
+ ATF_REQUIRE(kevent(kq, &kev, 1, NULL, 0, NULL) == 0);
+
+ ATF_REQUIRE(shutdown(sv[1], SHUT_WR) == 0);
+
+ ATF_REQUIRE(kevent(kq, NULL, 0, &kev, 1, NULL) == 1);
+ ATF_REQUIRE(kev.ident == (uintptr_t)sv[1] &&
+ kev.filter == EVFILT_WRITE &&
+ kev.flags == EV_EOF);
+
+ close(sv[0]);
+ close(sv[1]);
+}
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, getpeereid);
@@ -482,6 +505,7 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, peershutdown_wakeup_select);
ATF_TP_ADD_TC(tp, peershutdown_wakeup_poll);
ATF_TP_ADD_TC(tp, peershutdown_wakeup_kevent);
+ ATF_TP_ADD_TC(tp, ourshutdown_kevent);
return atf_no_error();
}