From 6cc02747a085a2f9aa9e21e764bed3ff5daf0eb1 Mon Sep 17 00:00:00 2001 From: Pierre Bourdon Date: Sat, 18 Feb 2012 17:28:53 +0100 Subject: [PATCH] Implement SO_FCNTL correctly on Linux --- .../Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp index b0b92fb876..4abfb2732c 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp @@ -813,11 +813,50 @@ u32 CWII_IPC_HLE_Device_net_ip_top::ExecuteCommand(u32 _Command, } else { - WARN_LOG(WII_IPC_NET, "UNKNOWN WTF?"); + WARN_LOG(WII_IPC_NET, "SO_FCNTL unknown command"); } return 0; #else - return fcntl(sock, cmd, arg); + // Map POSIX <-> Wii socket flags + // First one is POSIX, second one is Wii + static int mapping[][2] = { + { O_NONBLOCK, 0x4 }, + }; + + if (cmd == F_GETFL) + { + int flags = fcntl(sock, F_GETFL, 0); + int ret = 0; + + for (int i = 0; i < sizeof (mapping) / sizeof (mapping[0]); ++i) + if (flags & mapping[i][0]) + ret |= mapping[i][1]; + return ret; + } + else if (cmd == F_SETFL) + { + int posix_flags = 0; + + for (int i = 0; i < sizeof (mapping) / sizeof (mapping[0]); ++i) + { + if (arg & mapping[i][1]) + { + posix_flags |= mapping[i][0]; + arg &= ~mapping[i][1]; + } + } + + if (arg) + WARN_LOG(WII_IPC_NET, "SO_FCNTL F_SETFL unhandled flags: %08x", arg); + + int ret = fcntl(sock, F_SETFL, posix_flags); + return getNetErrorCode(ret, "SO_FCNTL", false); + } + else + { + WARN_LOG(WII_IPC_NET, "SO_FCNTL unknown command"); + } + return 0; #endif }