The branch main has been updated by glebius:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=60d5a4216b3479a2d62eb65f2cb03b799546dcbb

commit 60d5a4216b3479a2d62eb65f2cb03b799546dcbb
Author:     Gleb Smirnoff <gleb...@freebsd.org>
AuthorDate: 2025-09-02 20:34:12 +0000
Commit:     Gleb Smirnoff <gleb...@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();
 }

Reply via email to