summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorSepalani <sepalani@hotmail.fr>2017-06-04 02:51:26 +0100
committerSepalani <sepalani@hotmail.fr>2017-06-04 05:47:56 +0100
commitb327fd8b2c954bebc1cef234843b5b6fa0bfbf71 (patch)
treee2af47e9801579c210b41fcfc0f685b7ed240b38 /Source/Core
parentef20e85661050ae7cf805d86e706331d01e65624 (diff)
IOS/Network: Handle SO_EMFILE
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/IOS/Network/Socket.cpp46
-rw-r--r--Source/Core/Core/IOS/Network/Socket.h2
2 files changed, 31 insertions, 17 deletions
diff --git a/Source/Core/Core/IOS/Network/Socket.cpp b/Source/Core/Core/IOS/Network/Socket.cpp
index 772c86dce0..1b3ffbdf26 100644
--- a/Source/Core/Core/IOS/Network/Socket.cpp
+++ b/Source/Core/Core/IOS/Network/Socket.cpp
@@ -25,12 +25,15 @@
#else
#define ERRORCODE(name) name
#define EITHER(win32, posix) posix
+#define closesocket close
#endif
namespace IOS
{
namespace HLE
{
+constexpr int WII_SOCKET_FD_MAX = 24;
+
char* WiiSockMan::DecodeError(s32 ErrorCode)
{
#ifdef _WIN32
@@ -148,11 +151,7 @@ s32 WiiSocket::CloseFd()
s32 ReturnValue = 0;
if (fd >= 0)
{
-#ifdef _WIN32
s32 ret = closesocket(fd);
-#else
- s32 ret = close(fd);
-#endif
ReturnValue = WiiSockMan::GetNetErrorCode(ret, "CloseFd", false);
}
else
@@ -256,8 +255,7 @@ void WiiSocket::Update(bool read, bool write, bool except)
ret = static_cast<s32>(accept(fd, nullptr, nullptr));
}
- ret = WiiSockMan::GetInstance().AddSocket(ret);
- ReturnValue = WiiSockMan::GetNetErrorCode(ret, "SO_ACCEPT", true);
+ ReturnValue = WiiSockMan::GetInstance().AddSocket(ret, true);
ioctl.Log("IOCTL_SO_ACCEPT", LogTypes::IOS_NET);
break;
@@ -604,18 +602,36 @@ void WiiSocket::DoSock(Request request, SSL_IOCTL type)
pending_sockops.push_back(so);
}
-s32 WiiSockMan::AddSocket(s32 fd)
+s32 WiiSockMan::AddSocket(s32 fd, bool is_rw)
{
- if (fd >= 0)
+ const char* caller = is_rw ? "SO_ACCEPT" : "NewSocket";
+
+ if (fd < 0)
+ return GetNetErrorCode(fd, caller, is_rw);
+
+ s32 wii_fd;
+ for (wii_fd = 0; wii_fd < WII_SOCKET_FD_MAX; ++wii_fd)
+ {
+ // Find an available socket fd
+ if (WiiSockets.count(wii_fd) == 0)
+ break;
+ }
+
+ if (wii_fd == WII_SOCKET_FD_MAX)
+ {
+ // Close host socket
+ closesocket(fd);
+ wii_fd = -SO_EMFILE;
+ ERROR_LOG(IOS_NET, "%s failed: Too many open sockets, ret=%d", caller, wii_fd);
+ }
+ else
{
- s32 wii_fd = 0;
- while (WiiSockets.count(wii_fd) > 0)
- wii_fd += 1;
WiiSocket& sock = WiiSockets[wii_fd];
sock.SetFd(fd);
- return wii_fd;
}
- return fd;
+
+ SetLastNetError(wii_fd);
+ return wii_fd;
}
s32 WiiSockMan::NewSocket(s32 af, s32 type, s32 protocol)
@@ -625,9 +641,7 @@ s32 WiiSockMan::NewSocket(s32 af, s32 type, s32 protocol)
if (protocol != 0) // IPPROTO_IP
return -SO_EPROTONOSUPPORT;
s32 fd = static_cast<s32>(socket(af, type, protocol));
- s32 wii_fd = AddSocket(fd);
- s32 ret = GetNetErrorCode(wii_fd, "NewSocket", false);
- return ret;
+ return AddSocket(fd, false);
}
s32 WiiSockMan::GetHostSocket(s32 wii_fd) const
diff --git a/Source/Core/Core/IOS/Network/Socket.h b/Source/Core/Core/IOS/Network/Socket.h
index a1fbe61332..bbe2da76f2 100644
--- a/Source/Core/Core/IOS/Network/Socket.h
+++ b/Source/Core/Core/IOS/Network/Socket.h
@@ -221,7 +221,7 @@ public:
static void Convert(sockaddr_in const& from, WiiSockAddrIn& to, s32 addrlen = -1);
// NON-BLOCKING FUNCTIONS
s32 NewSocket(s32 af, s32 type, s32 protocol);
- s32 AddSocket(s32 fd);
+ s32 AddSocket(s32 fd, bool is_rw);
s32 GetHostSocket(s32 wii_fd) const;
s32 DeleteSocket(s32 s);
s32 GetLastNetError() const { return errno_last; }