From b1c70588fe3f1cdee936ea2d6d83c6170e6c4ab8 Mon Sep 17 00:00:00 2001 From: SSimco <37044560+SSimco@users.noreply.github.com> Date: Tue, 15 Nov 2022 18:03:46 +0200 Subject: [PATCH] Enable online features for Unix (#486) --- src/Cafe/OS/libs/nlibcurl/nlibcurl.cpp | 37 +++-- src/Cafe/OS/libs/nsysnet/nsysnet.cpp | 218 +++++++++++++++++-------- 2 files changed, 174 insertions(+), 81 deletions(-) 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<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 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