Common: Add SetPlatformSocketOptions function and SEND_FLAGS constant to Network.h to deal with OS-specific SIGPIPE behavior.

This commit is contained in:
Jordan Woyak 2026-02-04 19:35:30 -06:00
parent 2ffa7cec07
commit 5d2e93fa3e
4 changed files with 35 additions and 16 deletions

View File

@ -9,8 +9,9 @@
#include <vector>
#ifndef _WIN32
#include <cstring>
#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
#else
#include <WinSock2.h>
#endif
@ -19,6 +20,7 @@
#include "Common/BitUtils.h"
#include "Common/CommonFuncs.h"
#include "Common/Logging/Log.h"
#include "Common/Random.h"
#include "Common/StringUtil.h"
@ -586,4 +588,18 @@ const char* StrNetworkError()
#endif
return DecodeNetworkError(error_code);
}
bool SetPlatformSocketOptions(int fd [[maybe_unused]])
{
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
int opt_no_sigpipe = 1;
if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &opt_no_sigpipe, sizeof(opt_no_sigpipe)) < 0)
{
ERROR_LOG_FMT(COMMON, "Failed to set SO_NOSIGPIPE on socket: {}", StrNetworkError());
return false;
}
#endif
return true;
}
} // namespace Common

View File

@ -10,6 +10,10 @@
#include <type_traits>
#include <vector>
#if defined(__linux__) || defined(__HAIKU__)
#include <sys/socket.h>
#endif
#include "Common/CommonTypes.h"
struct sockaddr_in;
@ -279,4 +283,15 @@ NetworkErrorState SaveNetworkErrorState();
void RestoreNetworkErrorState(const NetworkErrorState& state);
const char* DecodeNetworkError(s32 error_code);
const char* StrNetworkError();
// Sets SO_NOSIGPIPE when available.
bool SetPlatformSocketOptions(int fd);
// Pass this to all `send` calls to avoid SIGPIPE.
#if defined(__linux__) || defined(__HAIKU__)
static constexpr int SEND_FLAGS = MSG_NOSIGNAL;
#else
static constexpr int SEND_FLAGS = 0;
#endif
} // namespace Common

View File

@ -31,11 +31,7 @@ using ws_ssize_t = int;
using ws_ssize_t = ssize_t;
#endif
#ifdef __linux__
#define SEND_FLAGS MSG_NOSIGNAL
#else
#define SEND_FLAGS 0
#endif
using Common::SEND_FLAGS;
TAPServerConnection::TAPServerConnection(const std::string& destination,
std::function<void(std::string&&)> recv_cb,
@ -114,11 +110,7 @@ static int ConnectToDestination(const std::string& destination)
return -1;
}
#ifdef __APPLE__
int opt_no_sigpipe = 1;
if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &opt_no_sigpipe, sizeof(opt_no_sigpipe)) < 0)
INFO_LOG_FMT(SP1, "Failed to set SO_NOSIGPIPE on socket\n");
#endif
Common::SetPlatformSocketOptions(fd);
if (connect(fd, reinterpret_cast<sockaddr*>(&ss), ss_size) == -1)
{

View File

@ -893,11 +893,7 @@ s32 WiiSockMan::AddSocket(s32 fd, bool is_rw)
sock.SetWiiFd(wii_fd);
m_ios.GetSystem().GetPowerPC().GetDebugInterface().NetworkLogger()->OnNewSocket(fd);
#ifdef __APPLE__
int opt_no_sigpipe = 1;
if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &opt_no_sigpipe, sizeof(opt_no_sigpipe)) < 0)
ERROR_LOG_FMT(IOS_NET, "Failed to set SO_NOSIGPIPE on socket");
#endif
Common::SetPlatformSocketOptions(fd);
// Wii UDP sockets can use broadcast address by default
if (!is_rw)