This commit is contained in:
georgemoralis 2025-06-05 21:34:24 -06:00 committed by GitHub
commit 31b0cc7788
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -28,6 +28,7 @@
#ifdef _WIN64
#include <Rpc.h>
#include <io.h>
#else
#include <uuid/uuid.h>
#endif
@ -230,6 +231,124 @@ int PS4_SYSV_ABI posix_getsockname(Libraries::Net::OrbisNetId s,
LOG_ERROR(Lib_Net, "error code returned : {:#x}", (u32)returncode);
return -1;
}
#ifdef _WIN32
int IsSocket(int fd) {
intptr_t handle = _get_osfhandle(fd);
WSANETWORKEVENTS ne;
SOCKET s = (SOCKET)handle;
WSAEnumNetworkEvents(s, NULL, &ne);
return (WSAGetLastError() != WSAENOTSOCK);
}
#endif
int PS4_SYSV_ABI posix_select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds,
timeval* timeout) {
#ifdef _WIN32
fd_set sock_r, sock_w, sock_x;
FD_ZERO(&sock_r);
FD_ZERO(&sock_w);
FD_ZERO(&sock_x);
int fd;
// Separate sockets for select()
for (fd = 0; fd < nfds; ++fd) {
if (IsSocket(fd)) {
SOCKET s = (SOCKET)_get_osfhandle(fd);
if (readfds && FD_ISSET(fd, readfds))
FD_SET(s, &sock_r);
if (writefds && FD_ISSET(fd, writefds))
FD_SET(s, &sock_w);
if (exceptfds && FD_ISSET(fd, exceptfds))
FD_SET(s, &sock_x);
}
}
int result = select(0, &sock_r, &sock_w, &sock_x, timeout);
int total_ready = result;
for (fd = 0; fd < nfds; ++fd) {
HANDLE h = (HANDLE)_get_osfhandle(fd);
DWORD type = GetFileType(h);
if (type == FILE_TYPE_UNKNOWN || IsSocket(fd))
continue;
// READ check
if (readfds && FD_ISSET(fd, readfds)) {
if (type == FILE_TYPE_PIPE) {
DWORD avail = 0;
if (PeekNamedPipe(h, NULL, 0, NULL, &avail, NULL) && avail > 0) {
total_ready++;
} else {
FD_CLR(fd, readfds);
}
} else if (type == FILE_TYPE_DISK) {
char tmp;
long pos = _lseek(fd, 0, SEEK_CUR);
if (_read(fd, &tmp, 1) > 0) {
_lseek(fd, pos, SEEK_SET);
total_ready++;
} else {
FD_CLR(fd, readfds);
}
}
}
// WRITE check
if (writefds && FD_ISSET(fd, writefds)) {
DWORD written = 0;
char dummy = 0;
BOOL writable = FALSE;
if (type == FILE_TYPE_PIPE) {
// Try writing 0 bytes to check if it's broken
writable = WriteFile(h, &dummy, 0, &written, NULL);
} else if (type == FILE_TYPE_DISK) {
writable = true; // Disk files are always "writable"
}
if (writable) {
total_ready++;
} else {
FD_CLR(fd, writefds);
}
}
// EXCEPTION check
if (exceptfds && FD_ISSET(fd, exceptfds)) {
DWORD err = 0, size = sizeof(err);
BOOL error_detected = false;
if (type == FILE_TYPE_PIPE) {
// Check broken pipe by trying non-blocking zero write
DWORD written;
char tmp = 0;
if (!WriteFile(h, &tmp, 0, &written, NULL)) {
DWORD e = GetLastError();
if (e == ERROR_NO_DATA || e == ERROR_BROKEN_PIPE) {
error_detected = true;
}
}
}
if (error_detected) {
total_ready++;
} else {
FD_CLR(fd, exceptfds);
}
}
}
return total_ready;
#else
// return select(nfds, readfds, writefds, exceptfds, timeout);
// nfds is shared with pipes , sockets , files in which we use separate maps so it can't work
// like this
LOG_ERROR(Lib_Net, "unimplemented (suck it linux) nfds={}", nfds);
return 0;
#endif
}
void RegisterKernel(Core::Loader::SymbolsResolver* sym) {
service_thread = std::jthread{KernelServiceThread};
@ -273,6 +392,7 @@ void RegisterKernel(Core::Loader::SymbolsResolver* sym) {
Libraries::Net::sceNetInetNtop); // TODO fix it to sys_ ...
LIB_FUNCTION("4n51s0zEf0c", "libScePosix", 1, "libkernel", 1, 1,
Libraries::Net::sceNetInetPton); // TODO fix it to sys_ ...
LIB_FUNCTION("T8fER+tIGgk", "libScePosix", 1, "libkernel", 1, 1, posix_select);
}
} // namespace Libraries::Kernel