From 7c213787ac017ad477eea3e1ac5414767e671549 Mon Sep 17 00:00:00 2001 From: Rookie <175737347+rooklz@users.noreply.github.com> Date: Thu, 22 Oct 2026 05:51:49 +0100 Subject: [PATCH] fix(libkernel): treat a socket direction that is already shut as shut on macOS hosts --- core/libs/prx/libkernel/Socket/src/Udp.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/core/libs/prx/libkernel/Socket/src/Udp.cpp b/core/libs/prx/libkernel/Socket/src/Udp.cpp index 3b412c4a5a..7642377219 100644 --- a/core/libs/prx/libkernel/Socket/src/Udp.cpp +++ b/core/libs/prx/libkernel/Socket/src/Udp.cpp @@ -1290,11 +1290,30 @@ int APS5_VABI bind_nid_postfix(int descriptor, const void* address, std::uint32_ if (!Address(address, length, native, size)) return -1; return ::bind(socket->value, reinterpret_cast(&native), size) ? Fail(NativeError()) : 0; } +namespace { +bool AlreadyShut(NativeSocket socket, int how) { +#ifdef __APPLE__ + if (errno != ENOTCONN) return false; + sockaddr_storage peer{}; + socklen_t size = sizeof(peer); + if (::getpeername(socket, reinterpret_cast(&peer), &size)) { + errno = ENOTCONN; + return false; + } + return how != SHUT_RDWR || ::shutdown(socket, SHUT_WR) == 0 || errno == ENOTCONN; +#else + (void)socket; + (void)how; + return false; +#endif +} +} + int APS5_VABI shutdown_nid_postfix(int descriptor, int how) { const auto socket = Lookup(descriptor); if (!socket) return -1; if (how < 0 || how > 2) return Fail(22); - if (::shutdown(socket->value, how)) return Fail(NativeError()); + if (::shutdown(socket->value, how) && !AlreadyShut(socket->value, how)) return Fail(NativeError()); std::lock_guard lock(socket->modeMutex); if (how != 1) socket->receiveShut = true; if (how != 0) socket->sendShut = true;