Merge pull request #744 from Blizzeq/fix/net-send-sigpipe

fix(net): keep SIGPIPE from killing the process on Linux sends
This commit is contained in:
Dean 2026-10-06 12:23:42 +13:00 committed by GitHub
commit e51edb4dc2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 14 additions and 3 deletions

View File

@ -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<const char*>(buf), static_cast<int>(len), 0);
const int result = ::send(socket.native->value, static_cast<const char*>(buf), static_cast<int>(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<const char*>(buf), static_cast<int>(len), 0);
result = ::send(socket.native->value, static_cast<const char*>(buf), static_cast<int>(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<const char*>(buf), static_cast<int>(len), 0,
result = ::sendto(socket.native->value, static_cast<const char*>(buf), static_cast<int>(len), NATIVE_SEND_FLAGS,
reinterpret_cast<const sockaddr*>(&destination), destination_length);
}
return result >= 0 ? result : fail(native_error());

View File

@ -1,9 +1,11 @@
#include "prx/libc/include/general/VabiMacros.hpp"
#include "SceTypes.hpp"
#include <array>
#include <chrono>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <thread>
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);