diff options
| author | Sepalani <sepalani@hotmail.fr> | 2022-05-27 14:07:59 +0400 |
|---|---|---|
| committer | Sepalani <sepalani@hotmail.fr> | 2022-06-08 19:06:42 +0400 |
| commit | d7135daff5d3c6aab91b4600875d234dff367f82 (patch) | |
| tree | 60369d294a106bd9ca43385f50617d820e751298 /Source/Core | |
| parent | c53a4c8c1a23a8e8bc164030fd6ea705b8ffa3dd (diff) | |
Socket: Fix some errors related to non-blocking connect
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/IOS/Network/Socket.cpp | 32 | ||||
| -rw-r--r-- | Source/Core/Core/IOS/Network/Socket.h | 1 |
2 files changed, 33 insertions, 0 deletions
diff --git a/Source/Core/Core/IOS/Network/Socket.cpp b/Source/Core/Core/IOS/Network/Socket.cpp index 29af6231d0..dcccf5977f 100644 --- a/Source/Core/Core/IOS/Network/Socket.cpp +++ b/Source/Core/Core/IOS/Network/Socket.cpp @@ -575,6 +575,16 @@ void WiiSocket::Update(bool read, bool write, bool except) { case IOCTLV_SO_SENDTO: { + // The Wii allows a socket with a connection in progress to use + // sendto(). This might not be supported by the operating system. + // We have to enforce it manually. + connecting_state = GetConnectingState(); + if (nonBlock && IsTCP() && connecting_state == ConnectingState::Connecting) + { + ReturnValue = -SO_EAGAIN; + break; + } + u32 flags = Memory::Read_U32(BufferIn2 + 0x04); u32 has_destaddr = Memory::Read_U32(BufferIn2 + 0x08); @@ -612,6 +622,16 @@ void WiiSocket::Update(bool read, bool write, bool except) } case IOCTLV_SO_RECVFROM: { + // The Wii allows a socket with a connection in progress to use + // recvfrom(). This might not be supported by the operating system. + // We have to enforce it manually. + connecting_state = GetConnectingState(); + if (nonBlock && IsTCP() && connecting_state == ConnectingState::Connecting) + { + ReturnValue = -SO_EAGAIN; + break; + } + u32 flags = Memory::Read_U32(BufferIn + 0x04); // Not a string, Windows requires a char* for recvfrom char* data = (char*)Memory::GetPointer(BufferOut); @@ -791,6 +811,18 @@ WiiSocket::ConnectingState WiiSocket::GetConnectingState() const return connecting_state; } +bool WiiSocket::IsTCP() const +{ + const auto state = Common::SaveNetworkErrorState(); + Common::ScopeGuard guard([&state] { Common::RestoreNetworkErrorState(state); }); + + int socket_type; + socklen_t option_length = sizeof(socket_type); + return getsockopt(fd, SOL_SOCKET, SO_TYPE, reinterpret_cast<char*>(&socket_type), + &option_length) == 0 && + socket_type == SOCK_STREAM; +} + const WiiSocket::Timeout& WiiSocket::GetTimeout() { if (!timeout.has_value()) diff --git a/Source/Core/Core/IOS/Network/Socket.h b/Source/Core/Core/IOS/Network/Socket.h index 9e2509fcc0..143391cd89 100644 --- a/Source/Core/Core/IOS/Network/Socket.h +++ b/Source/Core/Core/IOS/Network/Socket.h @@ -223,6 +223,7 @@ private: void UpdateConnectingState(s32 connect_rv); ConnectingState GetConnectingState() const; bool IsValid() const { return fd >= 0; } + bool IsTCP() const; s32 fd = -1; s32 wii_fd = -1; |
