s32 socketselect(s32 nfds, vm::ptr<fd_set> readfds, vm::ptr<fd_set> writefds, vm::ptr<fd_set> exceptfds, vm::ptr<timeval> timeout) { libnet.warning("socketselect(nfds=%d, readfds=*0x%x, writefds=*0x%x, exceptfds=*0x%x, timeout=*0x%x)", nfds, readfds, writefds, exceptfds, timeout); ::timeval _timeout; if (timeout) { _timeout.tv_sec = timeout->tv_sec; _timeout.tv_usec = timeout->tv_usec; } //libnet.error("timeval: %d . %d", _timeout.tv_sec, _timeout.tv_usec); ::fd_set _readfds; ::fd_set _writefds; ::fd_set _exceptfds; // Copy the fd_sets to native ones copy_fdset(&_readfds, readfds); copy_fdset(&_writefds, writefds); copy_fdset(&_exceptfds, exceptfds); s32 ret = ::select(nfds, &_readfds, &_writefds, &_exceptfds, timeout ? &_timeout : NULL); get_errno() = getLastError(); if (getLastError() >= 0) { libnet.error("socketselect(): error %d", getLastError()); } //return ret; return CELL_OK; }
s32 socketselect(s32 nfds, vm::ptr<fd_set> readfds, vm::ptr<fd_set> writefds, vm::ptr<fd_set> exceptfds, vm::ptr<timeval> timeout) { libnet.warning("socketselect(nfds=%d, readfds=*0x%x, writefds=*0x%x, exceptfds=*0x%x, timeout=*0x%x)", nfds, readfds, writefds, exceptfds, timeout); ::timeval _timeout; if (timeout) { _timeout.tv_sec = timeout->tv_sec; _timeout.tv_usec = timeout->tv_usec; } //libnet.error("timeval: %d . %d", _timeout.tv_sec, _timeout.tv_usec); ::fd_set _readfds; ::fd_set _writefds; ::fd_set _exceptfds; // Copy the fd_sets to native ones copy_fdset(&_readfds, readfds); copy_fdset(&_writefds, writefds); copy_fdset(&_exceptfds, exceptfds); #ifdef _WIN32 // On Unix, when the sets are empty (thus nothing to wait on), it waits until the timeout. // This behaviour is often used to "sleep" on Unix based systems. // WinSock in such case returns WSAEINVAL and doesn't allow such behaviour. // Since it's not possible on Windows, we just return and say that the timeout is over and hope that it's good enough. if (_readfds.fd_count == 0 && _writefds.fd_count == 0 && _exceptfds.fd_count == 0) { return 0; // Timeout! } #endif // There's no good way to determine nfds and it shouldn't be too slow, so let's let it check the whole set. It also isn't used on Windows. s32 ret = ::select(FD_SETSIZE, &_readfds, &_writefds, &_exceptfds, timeout ? &_timeout : nullptr); if (ret < 0) { libnet.error("socketselect(): error %d", get_errno() = get_last_error()); return -1; } return ret; }