summarylogtreecommitdiffstats
path: root/online.diff
diff options
context:
space:
mode:
Diffstat (limited to 'online.diff')
-rw-r--r--online.diff643
1 files changed, 643 insertions, 0 deletions
diff --git a/online.diff b/online.diff
new file mode 100644
index 000000000000..cfac0e3fd8fe
--- /dev/null
+++ b/online.diff
@@ -0,0 +1,643 @@
+diff --git a/src/Cafe/OS/libs/nlibcurl/nlibcurl.cpp b/src/Cafe/OS/libs/nlibcurl/nlibcurl.cpp
+index 5ec75e6b..d32c51f2 100644
+--- a/src/Cafe/OS/libs/nlibcurl/nlibcurl.cpp
++++ b/src/Cafe/OS/libs/nlibcurl/nlibcurl.cpp
+@@ -455,11 +455,6 @@ void export_curl_multi_fdset(PPCInterpreter_t* hCPU)
+ ppcDefineParamMEMPTR(exceptionFd, wu_fd_set, 3);
+ ppcDefineParamU32BEPtr(maxFd, 4);
+
+-#if BOOST_OS_LINUX || BOOST_OS_MACOS
+- cemuLog_log(LogType::Force, "curl_multi_fdset(...) - todo");
+-
+- osLib_returnFromFunction(hCPU, 0);
+-#else
+ fd_set h_readFd;
+ fd_set h_writeFd;
+ fd_set h_exceptionFd;
+@@ -475,17 +470,36 @@ void export_curl_multi_fdset(PPCInterpreter_t* hCPU)
+ nsysnet::wuResetFD(exceptionFd.GetPtr());
+
+ sint32 c_maxFD = -1;
+- // fd read set
+- for (uint32 i = 0; i < h_readFd.fd_count; i++)
++
++ auto hostFdSet = [&](SOCKET s, wu_fd_set* fds)
+ {
+- sint32 wuSocket = nsysnet_getVirtualSocketHandleFromHostHandle(h_readFd.fd_array[i]);
++ sint32 wuSocket = nsysnet_getVirtualSocketHandleFromHostHandle(s);
+ if (wuSocket < 0)
+- wuSocket = nsysnet_createVirtualSocketFromExistingSocket(h_readFd.fd_array[i]);
++ wuSocket = nsysnet_createVirtualSocketFromExistingSocket(s);
+ if (wuSocket >= 0)
+ {
+ c_maxFD = std::max(wuSocket, c_maxFD);
+- nsysnet::wuSetFD(readFd.GetPtr(), wuSocket);
++ nsysnet::wuSetFD(fds, wuSocket);
+ }
++ };
++
++#if BOOST_OS_UNIX
++ for (int s = 0; s < h_maxFd + 1; s++)
++ {
++ if(FD_ISSET(s, &h_readFd))
++ hostFdSet(s, readFd.GetPtr());
++
++ if(FD_ISSET(s, &h_writeFd))
++ hostFdSet(s, writeFd.GetPtr());
++
++ if(FD_ISSET(s, &h_exceptionFd))
++ hostFdSet(s, exceptionFd.GetPtr());
++ }
++#else
++ // fd read set
++ for (uint32 i = 0; i < h_readFd.fd_count; i++)
++ {
++ hostFdSet(h_readFd.fd_array[i], readFd.GetPtr());
+ }
+ // fd write set
+ for (uint32 i = 0; i < h_writeFd.fd_count; i++)
+@@ -497,11 +511,10 @@ void export_curl_multi_fdset(PPCInterpreter_t* hCPU)
+ {
+ cemu_assert_debug(false);
+ }
++#endif
+
+ *maxFd = c_maxFD;
+ osLib_returnFromFunction(hCPU, result);
+-#endif
+-
+ }
+
+ void export_curl_multi_setopt(PPCInterpreter_t* hCPU)
+diff --git a/src/Cafe/OS/libs/nsysnet/nsysnet.cpp b/src/Cafe/OS/libs/nsysnet/nsysnet.cpp
+index ade207f9..5a8081e2 100644
+--- a/src/Cafe/OS/libs/nsysnet/nsysnet.cpp
++++ b/src/Cafe/OS/libs/nsysnet/nsysnet.cpp
+@@ -6,8 +6,24 @@
+
+ #include "Common/socket.h"
+
++#if BOOST_OS_UNIX
++
++#define WSAEWOULDBLOCK EWOULDBLOCK
++#define WSAEINPROGRESS EINPROGRESS
++#define WSAESHUTDOWN ESHUTDOWN
++#define WSAECONNABORTED ECONNABORTED
++#define WSAHOST_NOT_FOUND EAI_NONAME
++
++#define GETLASTERR errno
++
++#endif // BOOST_OS_UNIX
++
+ #if BOOST_OS_WINDOWS
+
++#define GETLASTERR WSAGetLastError()
++
++#endif //BOOST_OS_WINDOWS
++
+ #define WU_AF_INET 2
+
+ #define WU_SOCK_STREAM 1
+@@ -50,8 +66,10 @@ bool sockLibReady = false;
+ void nsysnetExport_socket_lib_init(PPCInterpreter_t* hCPU)
+ {
+ sockLibReady = true;
++#if BOOST_OS_WINDOWS
+ WSADATA wsa;
+ WSAStartup(MAKEWORD(2, 2), &wsa);
++#endif // BOOST_OS_WINDOWS
+ osLib_returnFromFunction(hCPU, 0); // 0 -> Success
+ }
+
+@@ -200,7 +218,9 @@ sint32 _getFreeSocketHandle()
+ return 0;
+ }
+
++#if BOOST_OS_WINDOWS
+ #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
++#endif // BOOST_OS_WINDOWS
+
+ WUSOCKET nsysnet_createVirtualSocket(sint32 family, sint32 type, sint32 protocol)
+ {
+@@ -219,6 +239,7 @@ WUSOCKET nsysnet_createVirtualSocket(sint32 family, sint32 type, sint32 protocol
+ virtualSocketTable[s - 1] = vs;
+ // init host socket
+ vs->s = socket(family, type, protocol);
++ #if BOOST_OS_WINDOWS
+ // disable reporting of PORT_UNREACHABLE for UDP sockets
+ if (protocol == IPPROTO_UDP)
+ {
+@@ -226,21 +247,14 @@ WUSOCKET nsysnet_createVirtualSocket(sint32 family, sint32 type, sint32 protocol
+ DWORD dwBytesReturned = 0;
+ WSAIoctl(vs->s, SIO_UDP_CONNRESET, &bNewBehavior, sizeof bNewBehavior, NULL, 0, &dwBytesReturned, NULL, NULL);
+ }
++ #endif // BOOST_OS_WINDOWS
+ return vs->handle;
+ }
+
+ WUSOCKET nsysnet_createVirtualSocketFromExistingSocket(SOCKET existingSocket)
+ {
+ forceLogDebug_printf("nsysnet_createVirtualSocketFromExistingSocket - incomplete");
+- // SO_TYPE -> type
+- // SO_BSP_STATE -> protocol + other info
+- // SO_PROTOCOL_INFO -> protocol + type?
+-
+- WSAPROTOCOL_INFO protocolInfo = { 0 };
+- int optLen = sizeof(protocolInfo);
+- getsockopt(existingSocket, SOL_SOCKET, SO_PROTOCOL_INFO, (char*)&protocolInfo, &optLen);
+
+- // todo - translate protocolInfo
+
+ sint32 s = _getFreeSocketHandle();
+ if (s == 0)
+@@ -250,9 +264,34 @@ WUSOCKET nsysnet_createVirtualSocketFromExistingSocket(SOCKET existingSocket)
+ }
+ virtualSocket_t* vs = (virtualSocket_t*)malloc(sizeof(virtualSocket_t));
+ memset(vs, 0, sizeof(virtualSocket_t));
++#if BOOST_OS_WINDOWS
++ // SO_TYPE -> type
++ // SO_BSP_STATE -> protocol + other info
++ // SO_PROTOCOL_INFO -> protocol + type?
++
++ WSAPROTOCOL_INFO protocolInfo = { 0 };
++ int optLen = sizeof(protocolInfo);
++ getsockopt(existingSocket, SOL_SOCKET, SO_PROTOCOL_INFO, (char*)&protocolInfo, &optLen);
++ // todo - translate protocolInfo
+ vs->family = protocolInfo.iAddressFamily;
+ vs->type = protocolInfo.iSocketType;
+ vs->protocol = protocolInfo.iSocketType;
++#else
++ {
++ int type;
++ socklen_t optlen;
++ getsockopt(vs->s, SOL_SOCKET, SO_TYPE, &type, &optlen);
++ vs->type = type;
++ vs->protocol = type;
++ }
++ {
++ sockaddr saddr;
++ socklen_t len;
++ getsockname(vs->s, &saddr, &len);
++ vs->family = saddr.sa_family;
++ }
++#endif
++
+ vs->handle = s;
+ virtualSocketTable[s - 1] = vs;
+ vs->s = existingSocket;
+@@ -395,7 +434,19 @@ void nsysnetExport_socketclose(PPCInterpreter_t* hCPU)
+ }
+ osLib_returnFromFunction(hCPU, 0);
+ }
+-
++sint32 _socket_nonblock(SOCKET s, u_long mode)
++{
++#if BOOST_OS_WINDOWS
++ return ioctlsocket(s, FIONBIO, &mode);
++#else
++ int flags = fcntl(s, F_GETFL);
++ if(mode)
++ flags |= O_NONBLOCK;
++ else
++ flags &= ~O_NONBLOCK;
++ return fcntl(s, F_SETFL, flags);
++#endif
++}
+ void nsysnetExport_setsockopt(PPCInterpreter_t* hCPU)
+ {
+ socketLog_printf("setsockopt(%d,0x%x,0x%05x,0x%08x,%d)", hCPU->gpr[3], hCPU->gpr[4], hCPU->gpr[5], hCPU->gpr[6], hCPU->gpr[7]);
+@@ -441,7 +492,7 @@ void nsysnetExport_setsockopt(PPCInterpreter_t* hCPU)
+ else
+ cemu_assert_suspicious();
+ u_long mode = 1;
+- ioctlsocket(vs->s, FIONBIO, &mode);
++ _socket_nonblock(vs->s, mode);
+ vs->isNonBlocking = true;
+ }
+ else if (optname == WU_SO_NONBLOCK)
+@@ -450,16 +501,16 @@ void nsysnetExport_setsockopt(PPCInterpreter_t* hCPU)
+ assert_dbg();
+ sint32 optvalLE = _swapEndianU32(*(uint32*)optval);
+ u_long mode = optvalLE; // 1 -> enable, 0 -> disable
+- ioctlsocket(vs->s, FIONBIO, &mode);
++ _socket_nonblock(vs->s, mode);
+ vs->isNonBlocking = mode != 0;
+ }
+ else if (optname == WU_SO_KEEPALIVE)
+ {
+- // todo
++ cemuLog_logDebug(LogType::Socket, "todo: setsockopt() for WU_SO_KEEPALIVE");
+ }
+ else if (optname == WU_SO_WINSCALE)
+ {
+- // todo
++ cemuLog_logDebug(LogType::Socket, "todo: setsockopt() for WU_SO_WINSCALE");
+ }
+ else if (optname == WU_SO_RCVBUF)
+ {
+@@ -549,9 +600,9 @@ void nsysnetExport_getsockopt(PPCInterpreter_t* hCPU)
+ if (optname == WU_SO_LASTERROR)
+ {
+ int optvalLE = 0;
+- int optlenLE = 4;
++ socklen_t optlenLE = 4;
+ r = getsockopt(vs->s, hostLevel, SO_ERROR, (char*)&optvalLE, &optlenLE);
+- r = _translateError(r, WSAGetLastError());
++ r = _translateError(r, GETLASTERR);
+ if (memory_readU32(optlenMPTR) != 4)
+ assert_dbg();
+ memory_writeU32(optlenMPTR, 4);
+@@ -563,9 +614,9 @@ void nsysnetExport_getsockopt(PPCInterpreter_t* hCPU)
+ else if (optname == WU_SO_RCVBUF)
+ {
+ int optvalLE = 0;
+- int optlenLE = 4;
++ socklen_t optlenLE = 4;
+ r = getsockopt(vs->s, hostLevel, SO_RCVBUF, (char*)&optvalLE, &optlenLE);
+- r = _translateError(r, WSAGetLastError());
++ r = _translateError(r, GETLASTERR);
+ if (memory_readU32(optlenMPTR) != 4)
+ assert_dbg();
+ memory_writeU32(optlenMPTR, 4);
+@@ -575,9 +626,9 @@ void nsysnetExport_getsockopt(PPCInterpreter_t* hCPU)
+ else if (optname == WU_SO_SNDBUF)
+ {
+ int optvalLE = 0;
+- int optlenLE = 4;
++ socklen_t optlenLE = 4;
+ r = getsockopt(vs->s, hostLevel, SO_SNDBUF, (char*)&optvalLE, &optlenLE);
+- r = _translateError(r, WSAGetLastError());
++ r = _translateError(r, GETLASTERR);
+ if (memory_readU32(optlenMPTR) != 4)
+ assert_dbg();
+ memory_writeU32(optlenMPTR, 4);
+@@ -737,7 +788,7 @@ void nsysnetExport_bind(PPCInterpreter_t* hCPU)
+ hostAddr.sa_family = _swapEndianU16(addr->sa_family);
+ memcpy(hostAddr.sa_data, addr->sa_data, 14);
+ sint32 hr = bind(vs->s, &hostAddr, sizeof(sockaddr));
+- r = _translateError(hr, WSAGetLastError());
++ r = _translateError(hr, GETLASTERR);
+
+
+ socketLog_printf("bind address: %d.%d.%d.%d:%d result: %d", addr->sa_data[2], addr->sa_data[3], addr->sa_data[4], addr->sa_data[5], _swapEndianU16(*(uint16*)addr->sa_data), hr);
+@@ -797,7 +848,7 @@ void nsysnetExport_accept(PPCInterpreter_t* hCPU)
+ if (vs->isNonBlocking)
+ {
+ sockaddr hostAddr;
+- int hostLen = sizeof(sockaddr);
++ socklen_t hostLen = sizeof(sockaddr);
+ SOCKET hr = accept(vs->s, &hostAddr, &hostLen);
+ if (hr != SOCKET_ERROR)
+ {
+@@ -806,7 +857,7 @@ void nsysnetExport_accept(PPCInterpreter_t* hCPU)
+ }
+ else
+ {
+- r = _translateError((sint32)hr, (sint32)WSAGetLastError(), _ERROR_MODE_ACCEPT);
++ r = _translateError((sint32)hr, (sint32)GETLASTERR, _ERROR_MODE_ACCEPT);
+ }
+ sockaddr_host2guest(&hostAddr, addr);
+ }
+@@ -820,7 +871,6 @@ void nsysnetExport_accept(PPCInterpreter_t* hCPU)
+ osLib_returnFromFunction(hCPU, r);
+ }
+
+-
+ void nsysnetExport_connect(PPCInterpreter_t* hCPU)
+ {
+ socketLog_printf("connect(%d,0x%08x,%d)", hCPU->gpr[3], hCPU->gpr[4], hCPU->gpr[5]);
+@@ -844,7 +894,7 @@ void nsysnetExport_connect(PPCInterpreter_t* hCPU)
+ sint32 hr = connect(vs->s, &hostAddr, sizeof(sockaddr));
+ forceLog_printf("Attempt connect to %d.%d.%d.%d:%d", (sint32)(uint8)hostAddr.sa_data[2], (sint32)(uint8)hostAddr.sa_data[3], (sint32)(uint8)hostAddr.sa_data[4], (sint32)(uint8)hostAddr.sa_data[5], _swapEndianU16(*(uint16*)hostAddr.sa_data+0));
+
+- r = _translateError(hr, WSAGetLastError(), _ERROR_MODE_CONNECT);
++ r = _translateError(hr, GETLASTERR, _ERROR_MODE_CONNECT);
+
+ osLib_returnFromFunction(hCPU, r);
+ }
+@@ -852,7 +902,7 @@ void nsysnetExport_connect(PPCInterpreter_t* hCPU)
+ void _setSocketSendRecvNonBlockingMode(SOCKET s, bool isNonBlocking)
+ {
+ u_long mode = isNonBlocking ? 1 : 0;
+- sint32 r = ioctlsocket(s, FIONBIO, &mode);
++ sint32 r = _socket_nonblock(s, mode);
+ }
+
+ void nsysnetExport_send(PPCInterpreter_t* hCPU)
+@@ -881,7 +931,7 @@ void nsysnetExport_send(PPCInterpreter_t* hCPU)
+
+ sint32 hr = send(vs->s, msg, len, hostFlags);
+ socketLog_printf("Sent %d bytes", hr);
+- _translateError(hr <= 0 ? -1 : 0, WSAGetLastError());
++ _translateError(hr <= 0 ? -1 : 0, GETLASTERR);
+ r = hr;
+
+ osLib_returnFromFunction(hCPU, r);
+@@ -930,7 +980,7 @@ void nsysnetExport_recv(PPCInterpreter_t* hCPU)
+ break;
+ if (tr == 0)
+ break; // connection closed
+- if (tr < 0 && WSAGetLastError() != WSAEWOULDBLOCK)
++ if (tr < 0 && GETLASTERR != WSAEWOULDBLOCK)
+ break;
+ // yield thread
+ coreinit::OSSleepTicks(coreinit::EspressoTime::GetTimerClock() / 5000); // let thread wait 0.2ms to give other threads CPU time
+@@ -940,7 +990,7 @@ void nsysnetExport_recv(PPCInterpreter_t* hCPU)
+ }
+ // receive
+ sint32 hr = recv(vs->s, msg, len, hostFlags);
+- _translateError(hr <= 0 ? -1 : 0, WSAGetLastError());
++ _translateError(hr <= 0 ? -1 : 0, GETLASTERR);
+ if (requestIsNonBlocking != vs->isNonBlocking)
+ _setSocketSendRecvNonBlockingMode(vs->s, vs->isNonBlocking);
+ socketLog_printf("Received %d bytes", hr);
+@@ -955,11 +1005,20 @@ struct wu_timeval
+ uint32 tv_usec;
+ };
+
+-void _translateFDSet(fd_set* hostSet, struct wu_fd_set* fdset, sint32 nfds)
++void _translateFDSet(fd_set* hostSet, struct wu_fd_set* fdset, sint32 nfds, int *hostnfds)
+ {
+- hostSet->fd_count = 0;
++ FD_ZERO(hostSet);
+ if (fdset == NULL)
+ return;
++
++#if BOOST_OS_UNIX
++ int maxfd;
++ if(hostnfds)
++ maxfd = *hostnfds;
++ else
++ maxfd = -1;
++#endif
++
+ uint32 mask = fdset->mask;
+ for (sint32 i = 0; i < nfds; i++)
+ {
+@@ -969,9 +1028,19 @@ void _translateFDSet(fd_set* hostSet, struct wu_fd_set* fdset, sint32 nfds)
+ virtualSocket_t* vs = nsysnet_getVirtualSocketObject(socketHandle);
+ if(vs == NULL)
+ continue; // socket invalid
+- hostSet->fd_array[hostSet->fd_count] = vs->s;
+- hostSet->fd_count++;
++
++#if BOOST_OS_UNIX
++ if(vs->s > maxfd)
++ maxfd = vs->s;
++#endif
++
++ FD_SET(vs->s, hostSet);
+ }
++
++#if BOOST_OS_UNIX
++ if(hostnfds)
++ *hostnfds = maxfd;
++#endif
+ }
+
+ void _translateFDSetRev(struct wu_fd_set* fdset, fd_set* hostSet, sint32 nfds)
+@@ -979,6 +1048,7 @@ void _translateFDSetRev(struct wu_fd_set* fdset, fd_set* hostSet, sint32 nfds)
+ if (fdset == NULL)
+ return;
+ uint32 mask = _swapEndianU32(0);
++#if BOOST_OS_WINDOWS
+ for (sint32 i = 0; i < (sint32)hostSet->fd_count; i++)
+ {
+ sint32 virtualSocketHandle = nsysnet_getVirtualSocketHandleFromHostHandle(hostSet->fd_array[i]);
+@@ -986,7 +1056,15 @@ void _translateFDSetRev(struct wu_fd_set* fdset, fd_set* hostSet, sint32 nfds)
+ cemu_assert_debug(false);
+ mask |= (1<<virtualSocketHandle);
+ }
++#else
++ for (sint32 i = 0; i < WU_SOCKET_LIMIT; i++)
++ {
++ if (virtualSocketTable[i] && virtualSocketTable[i]->s && FD_ISSET(virtualSocketTable[i]->s, hostSet))
++ mask |= (1 << virtualSocketTable[i]->handle);
++ }
++#endif
+ fdset->mask = mask;
++
+ }
+
+ void nsysnetExport_select(PPCInterpreter_t* hCPU)
+@@ -1025,8 +1103,10 @@ void nsysnetExport_select(PPCInterpreter_t* hCPU)
+ // when fd sets are empty but timeout is set, then just wait and do nothing?
+ // Lost Reavers seems to expect this case to return 0 (it hardcodes empty fd sets and timeout comes from curl_multi_timeout)
+
+- //_setSockError(WU_SO_EINVAL);
+- // todo - sleep here
++ timeval tv;
++ tv.tv_sec = timeOut->tv_sec;
++ tv.tv_usec = timeOut->tv_usec;
++ select(0, nullptr, nullptr, nullptr, &tv);
+ socketLog_printf("select returned 0 because of empty fdsets with timeout");
+ osLib_returnFromFunction(hCPU, 0);
+
+@@ -1042,15 +1122,16 @@ void nsysnetExport_select(PPCInterpreter_t* hCPU)
+ uint32 startTime = GetTickCount();
+ while (true)
+ {
+- _translateFDSet(&_readfds, readfds, nfds);
+- _translateFDSet(&_writefds, writefds, nfds);
+- _translateFDSet(&_exceptfds, exceptfds, nfds);
+- r = select(0, readfds ? &_readfds : NULL, writefds ? &_writefds : NULL, exceptfds ? &_exceptfds : NULL, &tv);
++ int hostnfds = -1;
++ _translateFDSet(&_readfds, readfds, nfds, &hostnfds);
++ _translateFDSet(&_writefds, writefds, nfds, &hostnfds);
++ _translateFDSet(&_exceptfds, exceptfds, nfds, &hostnfds);
++ r = select(hostnfds + 1, readfds ? &_readfds : NULL, writefds ? &_writefds : NULL, exceptfds ? &_exceptfds : NULL, &tv);
+ if (r < 0)
+ {
+ forceLogDebug_printf("select() failed");
+ // timeout
+- _translateError(r, WSAGetLastError());
++ _translateError(r, GETLASTERR);
+ //_setSockError(WU_SO_SUCCESS);
+ // in case of error, clear all FD sets (?)
+ if (readfds)
+@@ -1083,7 +1164,9 @@ void nsysnetExport_select(PPCInterpreter_t* hCPU)
+ }
+ else
+ {
+- socketLog_printf("select returned %d. Read %d Write %d Except %d", r, _readfds.fd_count, _writefds.fd_count, _exceptfds.fd_count);
++ // socketLog_printf("select returned %d. Read %d Write %d Except %d", r, _readfds.fd_count, _writefds.fd_count, _exceptfds.fd_count);
++ socketLog_printf("select returned %d.", r);
++
+ _translateFDSetRev(readfds, &_readfds, nfds);
+ _translateFDSetRev(writefds, &_writefds, nfds);
+ _translateFDSetRev(exceptfds, &_exceptfds, nfds);
+@@ -1116,7 +1199,7 @@ void nsysnetExport_getsockname(PPCInterpreter_t* hCPU)
+ else
+ {
+ struct sockaddr hostAddr;
+- sint32 hostLen = sizeof(struct sockaddr);
++ socklen_t hostLen = sizeof(struct sockaddr);
+ sint32 hr = getsockname(vs->s, &hostAddr, &hostLen);
+ if (hr == 0)
+ {
+@@ -1151,13 +1234,13 @@ void nsysnetExport_getpeername(PPCInterpreter_t* hCPU)
+ }
+
+ sockaddr saddr;
+- int saddrLen = sizeof(sockaddr);
++ socklen_t saddrLen = sizeof(sockaddr);
+
+ if (*nameLen < (uint32be)16)
+ assert_dbg();
+
+ sint32 r = getpeername(vs->s, &saddr, &saddrLen);
+- r = _translateError(r, WSAGetLastError());
++ r = _translateError(r, GETLASTERR);
+
+ name->sa_family = _swapEndianU16(saddr.sa_family);
+ memcpy(name->sa_data, saddr.sa_data, 14);
+@@ -1432,7 +1515,7 @@ void nsysnetExport_recvfrom(PPCInterpreter_t* hCPU)
+ if (vs->isNonBlocking)
+ requestIsNonBlocking = vs->isNonBlocking;
+
+- sint32 fromLenHost = *fromLen;
++ socklen_t fromLenHost = *fromLen;
+ sockaddr fromAddrHost;
+ sint32 wsaError = 0;
+
+@@ -1447,16 +1530,20 @@ void nsysnetExport_recvfrom(PPCInterpreter_t* hCPU)
+ return;
+ }
+ // use select to check for exceptions and read data
+- FD_SET fd_read;
+- FD_SET fd_exceptions;
++ fd_set fd_read;
++ fd_set fd_exceptions;
+ FD_ZERO(&fd_read);
+ FD_ZERO(&fd_exceptions);
+ FD_SET(vs->s, &fd_read);
+ FD_SET(vs->s, &fd_exceptions);
+- TIMEVAL t;
++ timeval t;
+ t.tv_sec = 0;
+ t.tv_usec = 0;
+- sint32 count = select(0, &fd_read, NULL, &fd_exceptions, &t);
++ int nfds = 0;
++#if BOOST_OS_UNIX
++ nfds = vs->s + 1;
++#endif
++ sint32 count = select(nfds, &fd_read, NULL, &fd_exceptions, &t);
+ if (count > 0)
+ {
+ if (FD_ISSET(vs->s, &fd_exceptions))
+@@ -1467,7 +1554,7 @@ void nsysnetExport_recvfrom(PPCInterpreter_t* hCPU)
+ {
+ // data available
+ r = recvfrom(vs->s, msg, len, hostFlags, &fromAddrHost, &fromLenHost);
+- wsaError = WSAGetLastError();
++ wsaError = GETLASTERR;
+ if (r < 0)
+ cemu_assert_debug(false);
+ forceLogDebug_printf("recvfrom returned %d bytes", r);
+@@ -1504,7 +1591,7 @@ void nsysnetExport_recvfrom(PPCInterpreter_t* hCPU)
+ while (true)
+ {
+ r = recvfrom(vs->s, msg, len, hostFlags, &fromAddrHost, &fromLenHost);
+- wsaError = WSAGetLastError();
++ wsaError = GETLASTERR;
+ if (r < 0)
+ {
+ if (wsaError != WSAEWOULDBLOCK)
+@@ -1576,7 +1663,7 @@ void nsysnetExport_recvfrom_ex(PPCInterpreter_t* hCPU)
+ if (vs->isNonBlocking)
+ requestIsNonBlocking = vs->isNonBlocking;
+
+- sint32 fromLenHost = *fromLen;
++ socklen_t fromLenHost = *fromLen;
+ sockaddr fromAddrHost;
+ sint32 wsaError = 0;
+
+@@ -1591,16 +1678,20 @@ void nsysnetExport_recvfrom_ex(PPCInterpreter_t* hCPU)
+ return;
+ }
+ // use select to check for exceptions and read data
+- FD_SET fd_read;
+- FD_SET fd_exceptions;
++ fd_set fd_read;
++ fd_set fd_exceptions;
+ FD_ZERO(&fd_read);
+ FD_ZERO(&fd_exceptions);
+ FD_SET(vs->s, &fd_read);
+ FD_SET(vs->s, &fd_exceptions);
+- TIMEVAL t;
++ timeval t;
+ t.tv_sec = 0;
+ t.tv_usec = 0;
+- sint32 count = select(0, &fd_read, NULL, &fd_exceptions, &t);
++ int nfds = 0;
++#if BOOST_OS_UNIX
++ nfds = vs->s + 1;
++#endif
++ sint32 count = select(nfds, &fd_read, NULL, &fd_exceptions, &t);
+ if (count > 0)
+ {
+ if (FD_ISSET(vs->s, &fd_exceptions))
+@@ -1611,7 +1702,7 @@ void nsysnetExport_recvfrom_ex(PPCInterpreter_t* hCPU)
+ {
+ // data available
+ r = recvfrom(vs->s, msg, len, hostFlags, &fromAddrHost, &fromLenHost);
+- wsaError = WSAGetLastError();
++ wsaError = GETLASTERR;
+ if (r < 0)
+ {
+ cemu_assert_debug(false);
+@@ -1693,7 +1784,7 @@ void nsysnetExport_sendto(PPCInterpreter_t* hCPU)
+ while (true)
+ {
+ r = sendto(vs->s, msg, len, hostFlags, &toAddrHost, toLen);
+- wsaError = WSAGetLastError();
++ wsaError = GETLASTERR;
+ if (r < 0)
+ {
+ if (wsaError != WSAEWOULDBLOCK)
+@@ -1711,7 +1802,7 @@ void nsysnetExport_sendto(PPCInterpreter_t* hCPU)
+ // non blocking
+ _setSocketSendRecvNonBlockingMode(vs->s, true);
+ r = sendto(vs->s, msg, len, hostFlags, &toAddrHost, toLen);
+- wsaError = WSAGetLastError();
++ wsaError = GETLASTERR;
+ _setSocketSendRecvNonBlockingMode(vs->s, vs->isNonBlocking);
+ }
+
+@@ -1818,8 +1909,6 @@ void nsysnetExport_sendto_multi_ex(PPCInterpreter_t* hCPU)
+ osLib_returnFromFunction(hCPU, sendLenSum); // return value correct?
+ }
+
+-#endif
+-
+ namespace nsysnet
+ {
+ std::vector<NSSLInternalState_t> g_nsslInternalStates;
+@@ -2030,7 +2119,6 @@ namespace nsysnet
+ void nsysnet_load()
+ {
+
+- #if BOOST_OS_WINDOWS
+ osLib_addFunction("nsysnet", "socket_lib_init", nsysnetExport_socket_lib_init);
+
+ // socket API
+@@ -2071,7 +2159,6 @@ void nsysnet_load()
+ osLib_addFunction("nsysnet", "sendto_multi", nsysnetExport_sendto_multi);
+ osLib_addFunction("nsysnet", "sendto_multi_ex", nsysnetExport_sendto_multi_ex);
+
+-#endif
+
+ // NSSL API
+ osLib_addFunction("nsysnet", "NSSLCreateContext", nsysnet::export_NSSLCreateContext);
+@@ -2084,10 +2171,3 @@ void nsysnet_load()
+ osLib_addFunction("nsysnet", "NSSLExportInternalServerCertificate", nsysnet::export_NSSLExportInternalServerCertificate);
+ osLib_addFunction("nsysnet", "NSSLExportInternalClientCertificate", nsysnet::export_NSSLExportInternalClientCertificate);
+ }
+-
+-#if BOOST_OS_LINUX || BOOST_OS_MACOS
+-void nsysnet_notifyCloseSharedSocket(SOCKET existingSocket)
+-{
+-
+-}
+-#endif
+\ No newline at end of file