mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-15 22:21:25 +00:00
Fix for Windows ENOTCONN on connecting socket
Fixes Windows returns ENOTCONN when using recvfrom/sendto on connecting socket instead of the expected EAGAIN.
This commit is contained in:
parent
c570fd03d1
commit
d9e0d016c6
@ -239,7 +239,7 @@ std::optional<s32> lv2_socket_native::connect(const sys_net_sockaddr& addr)
|
||||
else
|
||||
{
|
||||
// TODO: check error formats (both native and translated)
|
||||
so_error = native_error ? get_last_error(false, native_error) : 0;
|
||||
so_error = native_error ? convert_error(false, native_error) : 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -270,7 +270,7 @@ s32 lv2_socket_native::connect_followup()
|
||||
}
|
||||
|
||||
// TODO: check error formats (both native and translated)
|
||||
return native_error ? -get_last_error(false, native_error) : 0;
|
||||
return native_error ? -convert_error(false, native_error) : 0;
|
||||
}
|
||||
|
||||
std::pair<s32, sys_net_sockaddr> lv2_socket_native::getpeername()
|
||||
@ -906,9 +906,10 @@ std::optional<std::tuple<s32, std::vector<u8>, sys_net_sockaddr>> lv2_socket_nat
|
||||
return {{0, {}, sn_addr}};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
const auto result = get_last_error(!so_nbio && (flags & SYS_NET_MSG_DONTWAIT) == 0, connecting);
|
||||
#else
|
||||
const auto result = get_last_error(!so_nbio && (flags & SYS_NET_MSG_DONTWAIT) == 0);
|
||||
#endif
|
||||
|
||||
if (result)
|
||||
{
|
||||
@ -974,7 +975,11 @@ std::optional<s32> lv2_socket_native::sendto(s32 flags, const std::vector<u8>& b
|
||||
return {native_result};
|
||||
}
|
||||
|
||||
result = get_last_error(!so_nbio && (flags & SYS_NET_MSG_DONTWAIT) == 0);
|
||||
#ifdef _WIN32
|
||||
get_last_error(!so_nbio && (flags & SYS_NET_MSG_DONTWAIT) == 0, connecting);
|
||||
#else
|
||||
get_last_error(!so_nbio && (flags & SYS_NET_MSG_DONTWAIT) == 0);
|
||||
#endif
|
||||
|
||||
if (result)
|
||||
{
|
||||
|
@ -20,17 +20,12 @@ int get_native_error()
|
||||
return native_error;
|
||||
}
|
||||
|
||||
sys_net_error get_last_error(bool is_blocking, int native_error)
|
||||
sys_net_error convert_error(bool is_blocking, int native_error, [[maybe_unused]] bool is_connecting)
|
||||
{
|
||||
// Convert the error code for socket functions to a one for sys_net
|
||||
sys_net_error result{};
|
||||
const char* name{};
|
||||
|
||||
if (!native_error)
|
||||
{
|
||||
native_error = get_native_error();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#define ERROR_CASE(error) \
|
||||
case WSA##error: \
|
||||
@ -92,6 +87,14 @@ sys_net_error get_last_error(bool is_blocking, int native_error)
|
||||
fmt::throw_exception("sys_net get_last_error(is_blocking=%d, native_error=%d): Unknown/illegal socket error", is_blocking, native_error);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// Windows will return SYS_NET_ENOTCONN when recvfrom/sendto is called on a socket that is connecting but not yet connected
|
||||
if (is_connecting && result == SYS_NET_ENOTCONN)
|
||||
{
|
||||
return SYS_NET_EAGAIN;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (name && result != SYS_NET_EWOULDBLOCK && result != SYS_NET_EINPROGRESS)
|
||||
{
|
||||
sys_net.error("Socket error %s", name);
|
||||
@ -111,6 +114,11 @@ sys_net_error get_last_error(bool is_blocking, int native_error)
|
||||
#undef ERROR_CASE
|
||||
}
|
||||
|
||||
sys_net_error get_last_error(bool is_blocking, bool is_connecting)
|
||||
{
|
||||
return convert_error(is_blocking, get_native_error(), is_connecting);
|
||||
}
|
||||
|
||||
sys_net_sockaddr native_addr_to_sys_net_addr(const ::sockaddr_storage& native_addr)
|
||||
{
|
||||
ensure(native_addr.ss_family == AF_INET || native_addr.ss_family == AF_UNSPEC);
|
||||
|
@ -18,7 +18,8 @@
|
||||
#include "Emu/Cell/lv2/sys_net.h"
|
||||
|
||||
int get_native_error();
|
||||
sys_net_error get_last_error(bool is_blocking, int native_error = 0);
|
||||
sys_net_error convert_error(bool is_blocking, int native_error, bool is_connecting = false);
|
||||
sys_net_error get_last_error(bool is_blocking, bool is_connecting = false);
|
||||
sys_net_sockaddr native_addr_to_sys_net_addr(const ::sockaddr_storage& native_addr);
|
||||
::sockaddr_in sys_net_addr_to_native_addr(const sys_net_sockaddr& sn_addr);
|
||||
bool is_ip_public_address(const ::sockaddr_in& addr);
|
||||
|
Loading…
x
Reference in New Issue
Block a user