@ -39,6 +39,11 @@ namespace Network {
namespace {
namespace {
enum class CallType {
Send ,
Other ,
} ;
# ifdef _WIN32
# ifdef _WIN32
using socklen_t = int ;
using socklen_t = int ;
@ -96,7 +101,7 @@ bool EnableNonBlock(SOCKET fd, bool enable) {
return ioctlsocket ( fd , FIONBIO , & value ) ! = SOCKET_ERROR ;
return ioctlsocket ( fd , FIONBIO , & value ) ! = SOCKET_ERROR ;
}
}
Errno TranslateNativeError ( int e ) {
Errno TranslateNativeError ( int e , CallType call_type = CallType : : Other ) {
switch ( e ) {
switch ( e ) {
case 0 :
case 0 :
return Errno : : SUCCESS ;
return Errno : : SUCCESS ;
@ -112,6 +117,14 @@ Errno TranslateNativeError(int e) {
return Errno : : AGAIN ;
return Errno : : AGAIN ;
case WSAECONNREFUSED :
case WSAECONNREFUSED :
return Errno : : CONNREFUSED ;
return Errno : : CONNREFUSED ;
case WSAECONNABORTED :
if ( call_type = = CallType : : Send ) {
// Winsock yields WSAECONNABORTED from `send` in situations where Unix
// systems, and actual Switches, yield EPIPE.
return Errno : : PIPE ;
} else {
return Errno : : CONNABORTED ;
}
case WSAECONNRESET :
case WSAECONNRESET :
return Errno : : CONNRESET ;
return Errno : : CONNRESET ;
case WSAEHOSTUNREACH :
case WSAEHOSTUNREACH :
@ -198,7 +211,7 @@ bool EnableNonBlock(int fd, bool enable) {
return fcntl ( fd , F_SETFL , flags ) = = 0 ;
return fcntl ( fd , F_SETFL , flags ) = = 0 ;
}
}
Errno TranslateNativeError ( int e ) {
Errno TranslateNativeError ( int e , CallType call_type = CallType : : Other ) {
switch ( e ) {
switch ( e ) {
case 0 :
case 0 :
return Errno : : SUCCESS ;
return Errno : : SUCCESS ;
@ -208,6 +221,10 @@ Errno TranslateNativeError(int e) {
return Errno : : INVAL ;
return Errno : : INVAL ;
case EMFILE :
case EMFILE :
return Errno : : MFILE ;
return Errno : : MFILE ;
case EPIPE :
return Errno : : PIPE ;
case ECONNABORTED :
return Errno : : CONNABORTED ;
case ENOTCONN :
case ENOTCONN :
return Errno : : NOTCONN ;
return Errno : : NOTCONN ;
case EAGAIN :
case EAGAIN :
@ -236,13 +253,13 @@ Errno TranslateNativeError(int e) {
# endif
# endif
Errno GetAndLogLastError ( ) {
Errno GetAndLogLastError ( CallType call_type = CallType : : Other ) {
# ifdef _WIN32
# ifdef _WIN32
int e = WSAGetLastError ( ) ;
int e = WSAGetLastError ( ) ;
# else
# else
int e = errno ;
int e = errno ;
# endif
# endif
const Errno err = TranslateNativeError ( e );
const Errno err = TranslateNativeError ( e , call_type );
if ( err = = Errno : : AGAIN | | err = = Errno : : TIMEDOUT | | err = = Errno : : INPROGRESS ) {
if ( err = = Errno : : AGAIN | | err = = Errno : : TIMEDOUT | | err = = Errno : : INPROGRESS ) {
// These happen during normal operation, so only log them at debug level.
// These happen during normal operation, so only log them at debug level.
LOG_DEBUG ( Network , " Socket operation error: {} " , Common : : NativeErrorToString ( e ) ) ;
LOG_DEBUG ( Network , " Socket operation error: {} " , Common : : NativeErrorToString ( e ) ) ;
@ -731,13 +748,17 @@ std::pair<s32, Errno> Socket::Send(std::span<const u8> message, int flags) {
ASSERT ( message . size ( ) < static_cast < size_t > ( std : : numeric_limits < int > : : max ( ) ) ) ;
ASSERT ( message . size ( ) < static_cast < size_t > ( std : : numeric_limits < int > : : max ( ) ) ) ;
ASSERT ( flags = = 0 ) ;
ASSERT ( flags = = 0 ) ;
int native_flags = 0 ;
# if YUZU_UNIX
native_flags | = MSG_NOSIGNAL ; // do not send us SIGPIPE
# endif
const auto result = send ( fd , reinterpret_cast < const char * > ( message . data ( ) ) ,
const auto result = send ( fd , reinterpret_cast < const char * > ( message . data ( ) ) ,
static_cast < int > ( message . size ( ) ) , 0 ) ;
static_cast < int > ( message . size ( ) ) , native_flags ) ;
if ( result ! = SOCKET_ERROR ) {
if ( result ! = SOCKET_ERROR ) {
return { static_cast < s32 > ( result ) , Errno : : SUCCESS } ;
return { static_cast < s32 > ( result ) , Errno : : SUCCESS } ;
}
}
return { - 1 , GetAndLogLastError ( ) } ;
return { - 1 , GetAndLogLastError ( CallType : : Send ) } ;
}
}
std : : pair < s32 , Errno > Socket : : SendTo ( u32 flags , std : : span < const u8 > message ,
std : : pair < s32 , Errno > Socket : : SendTo ( u32 flags , std : : span < const u8 > message ,
@ -759,7 +780,7 @@ std::pair<s32, Errno> Socket::SendTo(u32 flags, std::span<const u8> message,
return { static_cast < s32 > ( result ) , Errno : : SUCCESS } ;
return { static_cast < s32 > ( result ) , Errno : : SUCCESS } ;
}
}
return { - 1 , GetAndLogLastError ( ) } ;
return { - 1 , GetAndLogLastError ( CallType : : Send ) } ;
}
}
Errno Socket : : Close ( ) {
Errno Socket : : Close ( ) {