fix(net): report EPIPE for a send after shutdown on Windows

Winsock fails send, sendto and sendmsg on a socket shut down for writing
with WSAESHUTDOWN, which neither Windows error map handled, so libkernel
and libSceNet reported EIO. FreeBSD reports EPIPE there, and the Linux
maps already translate the host's EPIPE to 32. Map WSAESHUTDOWN to 32
in both.
This commit is contained in:
Zurisen 2026-10-08 20:50:09 +02:00
parent a291ae0f88
commit 2356aba27b
4 changed files with 8 additions and 0 deletions

View File

@ -112,6 +112,7 @@ int native_error() {
case WSAEINTR: return 4;
case WSAEINVAL: return NET_EINVAL;
case WSAENOTSOCK: return NET_ENOTSOCK;
case WSAESHUTDOWN: return 32;
default: return 5;
}
}

View File

@ -67,6 +67,7 @@ int NativeError() {
case WSAECONNREFUSED: return 61;
case WSAEINTR: return 4;
case WSAEINVAL: return 22;
case WSAESHUTDOWN: return 32;
default: return 5;
}
#else

View File

@ -25,6 +25,7 @@ std::int64_t APS5_VABI sceNetRecv(int, void*, std::size_t, int);
std::int64_t APS5_VABI sceNetSendto(int, const void*, std::size_t, int, const void*, std::uint32_t);
std::int64_t APS5_VABI sceNetRecvfrom(int, void*, std::size_t, int, void*, std::uint32_t*);
int APS5_VABI sceNetSocketClose(int);
int APS5_VABI sceNetShutdown(int, int);
int APS5_VABI sceNetSetsockopt(int, int, int, const void*, std::uint32_t);
int* APS5_VABI sceNetErrnoLoc(void);
int APS5_VABI sceNetEpollCreate(const char*, int);
@ -279,6 +280,8 @@ int main() {
Require(sceNetSend(client, request, sizeof(request), 0) == sizeof(request));
ready = {};
Require(sceNetEpollWait(epoll, &ready, 1, 1000000) == 1 && (ready.events & 1) && ready.ident == static_cast<std::uint64_t>(accepted));
Require(sceNetShutdown(accepted, 1) == 0);
Require(Failed(sceNetSend(accepted, request, sizeof(request), 0), 32));
Require(sceNetEpollDestroy(epoll) == 0);
Require(sceNetSocketClose(accepted) == 0);
bool send_failed = false;

View File

@ -14,6 +14,7 @@ int APS5_VABI accept_nid_postfix(int, void*, std::uint32_t*);
std::int64_t APS5_VABI send_nid_postfix(int, const void*, std::uint64_t, int);
std::int64_t APS5_VABI recv_nid_postfix(int, void*, std::uint64_t, int);
int APS5_VABI getpeername_nid_postfix(int, void*, std::uint32_t*);
int APS5_VABI shutdown_nid_postfix(int, int);
int APS5_VABI close_nid_postfix(int);
int* APS5_VABI __error_nid_postfix();
}
@ -53,6 +54,8 @@ int main() {
Require(send_nid_postfix(client, request, sizeof(request), 0x20000) == sizeof(request));
Require(recv_nid_postfix(accepted, received, sizeof(received), 0) == sizeof(received));
Require(std::strcmp(request, received) == 0);
Require(shutdown_nid_postfix(client, 1) == 0);
Require(send_nid_postfix(client, request, sizeof(request), 0x20000) == -1 && *__error_nid_postfix() == 32);
Require(close_nid_postfix(accepted) == 0);
#ifndef _WIN32