mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-27 16:02:37 +00:00
net: report open file and device descriptors ready in select (Cyberpunk 2077 Galaxy RNG seeding)
Co-authored-by: Artyom Zabroda <artyomzabroda@proton.me>
This commit is contained in:
1 parent
f5f4e7d48a
commit
a875d1b205
4 files changed
+40
-1
No files matched your search
@@ -410,6 +410,11 @@ std::filesystem::path GetRealFilename(const std::string& mounted_file_name) {
|
|||||||
return g_mount_points->ResolvePath(mounted_file_name);
|
return g_mount_points->ResolvePath(mounted_file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsOpenDescriptor(int d) {
|
||||||
|
const auto* file = g_files->GetFile(d);
|
||||||
|
return file != nullptr && file->opened;
|
||||||
|
}
|
||||||
|
|
||||||
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
|
||||||
int KYTY_SYSV_ABI KernelOpen(const char* path, int flags, uint16_t mode) {
|
int KYTY_SYSV_ABI KernelOpen(const char* path, int flags, uint16_t mode) {
|
||||||
PRINT_NAME();
|
PRINT_NAME();
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ void Mount(const std::filesystem::path& folder, const std::stri
|
|||||||
void Umount(const std::string& folder_or_point);
|
void Umount(const std::string& folder_or_point);
|
||||||
// Returns an empty path when the guest path has no mounted filesystem.
|
// Returns an empty path when the guest path has no mounted filesystem.
|
||||||
std::filesystem::path GetRealFilename(const std::string& mounted_file_name);
|
std::filesystem::path GetRealFilename(const std::string& mounted_file_name);
|
||||||
|
// Returns whether d is an open file, directory or device descriptor.
|
||||||
|
bool IsOpenDescriptor(int d);
|
||||||
|
|
||||||
int KYTY_SYSV_ABI KernelOpen(const char* path, int flags, uint16_t mode);
|
int KYTY_SYSV_ABI KernelOpen(const char* path, int flags, uint16_t mode);
|
||||||
int KYTY_SYSV_ABI KernelClose(int d);
|
int KYTY_SYSV_ABI KernelClose(int d);
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "common/emulatorConfig.h"
|
#include "common/emulatorConfig.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/threads.h"
|
#include "common/threads.h"
|
||||||
|
#include "kernel/fileSystem.h"
|
||||||
#include "kernel/pthread.h"
|
#include "kernel/pthread.h"
|
||||||
#include "libs/errno.h"
|
#include "libs/errno.h"
|
||||||
#include "libs/libs.h"
|
#include "libs/libs.h"
|
||||||
@@ -2577,6 +2578,7 @@ int KYTY_SYSV_ABI Select(int nfds, void* readfds, void* writefds, void* exceptfd
|
|||||||
|
|
||||||
std::vector<std::pair<int, NativeSocket>> descriptors;
|
std::vector<std::pair<int, NativeSocket>> descriptors;
|
||||||
std::vector<std::shared_ptr<SocketTransport>> stream_reads;
|
std::vector<std::shared_ptr<SocketTransport>> stream_reads;
|
||||||
|
std::vector<std::pair<void*, int>> ready_files;
|
||||||
int host_nfds = 0;
|
int host_nfds = 0;
|
||||||
for (int fd = 0; fd < nfds; fd++) {
|
for (int fd = 0; fd < nfds; fd++) {
|
||||||
const bool read = GuestFdIsSet(readfds, fd);
|
const bool read = GuestFdIsSet(readfds, fd);
|
||||||
@@ -2585,6 +2587,16 @@ int KYTY_SYSV_ABI Select(int nfds, void* readfds, void* writefds, void* exceptfd
|
|||||||
if (!read && !write && !except) {
|
if (!read && !write && !except) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// FreeBSD polls files and devices ready to read and write at once.
|
||||||
|
if (!IsSocket(fd) && LibKernel::FileSystem::IsOpenDescriptor(fd)) {
|
||||||
|
if (read) {
|
||||||
|
ready_files.emplace_back(readfds, fd);
|
||||||
|
}
|
||||||
|
if (write) {
|
||||||
|
ready_files.emplace_back(writefds, fd);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
NativeSocket socket = INVALID_NATIVE_SOCKET;
|
NativeSocket socket = INVALID_NATIVE_SOCKET;
|
||||||
std::shared_ptr<SocketTransport> transport;
|
std::shared_ptr<SocketTransport> transport;
|
||||||
#if !defined(_WIN32)
|
#if !defined(_WIN32)
|
||||||
@@ -2636,6 +2648,10 @@ int KYTY_SYSV_ABI Select(int nfds, void* readfds, void* writefds, void* exceptfd
|
|||||||
host_timeout.tv_usec = static_cast<decltype(host_timeout.tv_usec)>(guest_timeout->tv_usec);
|
host_timeout.tv_usec = static_cast<decltype(host_timeout.tv_usec)>(guest_timeout->tv_usec);
|
||||||
host_timeout_ptr = &host_timeout;
|
host_timeout_ptr = &host_timeout;
|
||||||
}
|
}
|
||||||
|
if (!ready_files.empty()) {
|
||||||
|
host_timeout = {};
|
||||||
|
host_timeout_ptr = &host_timeout;
|
||||||
|
}
|
||||||
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
@@ -2672,6 +2688,10 @@ int KYTY_SYSV_ABI Select(int nfds, void* readfds, void* writefds, void* exceptfd
|
|||||||
result++;
|
result++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (const auto& [fds, fd]: ready_files) {
|
||||||
|
GuestFdSet(fds, fd);
|
||||||
|
result++;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -324,6 +324,7 @@ void CheckSaveRename(const std::filesystem::path &root,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TestRandomDevices() {
|
void TestRandomDevices() {
|
||||||
|
namespace Net = Libs::Network::Net;
|
||||||
for (const auto* path : {"/dev/urandom", "/dev/random"}) {
|
for (const auto* path : {"/dev/urandom", "/dev/random"}) {
|
||||||
const int fd = FileSystem::KernelOpen(path, 0, 0);
|
const int fd = FileSystem::KernelOpen(path, 0, 0);
|
||||||
FileSystem::FileStat stat {};
|
FileSystem::FileStat stat {};
|
||||||
@@ -333,7 +334,18 @@ void TestRandomDevices() {
|
|||||||
std::array<uint8_t, 32> entropy {};
|
std::array<uint8_t, 32> entropy {};
|
||||||
Check(FileSystem::KernelRead(fd, entropy.data(), entropy.size()) == entropy.size(),
|
Check(FileSystem::KernelRead(fd, entropy.data(), entropy.size()) == entropy.size(),
|
||||||
"character device supplies requested entropy");
|
"character device supplies requested entropy");
|
||||||
|
// OpenSSL RAND_poll selects the device before reading it; a null timeout must not block.
|
||||||
|
std::array<uint64_t, 16> readable {};
|
||||||
|
readable[fd / 64] = uint64_t {1} << (fd % 64);
|
||||||
|
auto writable = readable;
|
||||||
|
const auto requested = readable;
|
||||||
|
Check(Net::Select(fd + 1, readable.data(), writable.data(), nullptr, nullptr) == 2 &&
|
||||||
|
readable == requested && writable == requested,
|
||||||
|
"select reports an entropy source ready at once");
|
||||||
Check(FileSystem::KernelClose(fd) == OK, "close entropy source");
|
Check(FileSystem::KernelClose(fd) == OK, "close entropy source");
|
||||||
|
Check(Net::Select(fd + 1, readable.data(), nullptr, nullptr, nullptr) == -1 &&
|
||||||
|
*Libs::Posix::GetErrorAddr() == Libs::Posix::POSIX_EBADF,
|
||||||
|
"select rejects a closed descriptor");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2453,8 +2465,8 @@ int main(int argc, char** argv) {
|
|||||||
TestAioBatches();
|
TestAioBatches();
|
||||||
CheckSaveRename(temporary.Path(), "first-save");
|
CheckSaveRename(temporary.Path(), "first-save");
|
||||||
CheckSaveRename(temporary.Path(), "replacement-save");
|
CheckSaveRename(temporary.Path(), "replacement-save");
|
||||||
FileSystem::Shutdown();
|
|
||||||
CheckSocketWakeup();
|
CheckSocketWakeup();
|
||||||
|
FileSystem::Shutdown();
|
||||||
CheckEtherAddressFormatting();
|
CheckEtherAddressFormatting();
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
TestNetCtlHostIpv4();
|
TestNetCtlHostIpv4();
|
||||||
|
|||||||
Reference in new issue
Block a user