diff --git a/core/libs/prx/libSceNet/Export.cpp b/core/libs/prx/libSceNet/Export.cpp index 456301ccf..f402f8b70 100644 --- a/core/libs/prx/libSceNet/Export.cpp +++ b/core/libs/prx/libSceNet/Export.cpp @@ -65,6 +65,7 @@ constexpr int NET_SO_NBIO = 0x1200; using NativeSocket = SOCKET; using NativeLength = int; constexpr NativeSocket INVALID_NATIVE_SOCKET = INVALID_SOCKET; +constexpr int NATIVE_SEND_FLAGS = 0; bool initialize_sockets() { static const int result = [] { WSADATA data{}; @@ -95,6 +96,7 @@ int native_error() { using NativeSocket = int; using NativeLength = socklen_t; constexpr NativeSocket INVALID_NATIVE_SOCKET = -1; +constexpr int NATIVE_SEND_FLAGS = MSG_NOSIGNAL; bool initialize_sockets() { return true; } void close_socket(NativeSocket socket) { ::close(socket); } int native_error() { @@ -115,6 +117,7 @@ int native_error() { case EINTR: return 4; case EINVAL: return NET_EINVAL; case ENOTSOCK: return NET_ENOTSOCK; + case EPIPE: return 32; default: return 5; } } @@ -484,7 +487,7 @@ int64_t APS5_VABI sceNetSend(int s, const void* buf, size_t len, int flags) { if (it == g_socks.end()) return fail(NET_EBADF); socket = it->second; } - const int result = ::send(socket.native->value, static_cast(buf), static_cast(len), 0); + const int result = ::send(socket.native->value, static_cast(buf), static_cast(len), NATIVE_SEND_FLAGS); return result >= 0 ? result : fail(native_error()); } @@ -502,13 +505,13 @@ int64_t APS5_VABI sceNetSendto(int s, const void* buf, size_t len, int flags, co int result; if (!to) { if (tolen != 0) return fail(NET_EINVAL); - result = ::send(socket.native->value, static_cast(buf), static_cast(len), 0); + result = ::send(socket.native->value, static_cast(buf), static_cast(len), NATIVE_SEND_FLAGS); } else { sockaddr_storage destination{}; NativeLength destination_length = 0; if (!guest_to_native_address(to, tolen, destination, destination_length)) return fail(NET_EINVAL); if (destination.ss_family != (socket.family == NET_AF_INET ? AF_INET : AF_INET6)) return fail(NET_EAFNOSUPPORT); - result = ::sendto(socket.native->value, static_cast(buf), static_cast(len), 0, + result = ::sendto(socket.native->value, static_cast(buf), static_cast(len), NATIVE_SEND_FLAGS, reinterpret_cast(&destination), destination_length); } return result >= 0 ? result : fail(native_error()); diff --git a/core/libs/tests/GuestSceNet.cpp b/core/libs/tests/GuestSceNet.cpp index aae168ecc..eda6e5954 100644 --- a/core/libs/tests/GuestSceNet.cpp +++ b/core/libs/tests/GuestSceNet.cpp @@ -1,9 +1,11 @@ #include "prx/libc/include/general/VabiMacros.hpp" #include "SceTypes.hpp" #include +#include #include #include #include +#include extern "C" { int APS5_VABI sceNetInit_nid_postfix(void); @@ -71,6 +73,12 @@ int main() { Require(std::strcmp(request, response) == 0); Require(sceNetEpollDestroy(epoll) == 0); Require(sceNetSocketClose(accepted) == 0); + bool send_failed = false; + for (int attempt = 0; attempt < 100 && !send_failed; ++attempt) { + send_failed = sceNetSend(client, request, sizeof(request), 0) < 0; + if (!send_failed) std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + Require(send_failed); Require(sceNetSocketClose(client) == 0); Require(sceNetSocketClose(listener) == 0);