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:
commit
e51edb4dc2
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue