mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-09 23:00:20 +02:00
To locate whether a path is in the emulated list, EmulatedFDManager::OpenAt() attemps to resolve the path. realpath() ends up calling readlinkat() on every path component, which is a lot of syscalls for every open() variant syscall. It also makes interaction with the rootfs complex and error-prone. There's a much easier way to do this: We just open the file without emulation and check its real path via get_fdpath(). This is just one readlink() syscall per open, instead of one per path component. If the file turns out to be emulated (uncommon case), we swap out the fds. This also decouples EmulatedFDManager from guest path resolution entirely, so it will never fall out of sync with the RootFS logic.
40 lines
1.1 KiB
C++
40 lines
1.1 KiB
C++
// SPDX-License-Identifier: MIT
|
|
/*
|
|
$info$
|
|
tags: LinuxSyscalls|common
|
|
$end_info$
|
|
*/
|
|
|
|
#pragma once
|
|
#include <FEXCore/Config/Config.h>
|
|
#include <FEXCore/fextl/unordered_map.h>
|
|
#include <FEXCore/fextl/string.h>
|
|
|
|
#include <cstdint>
|
|
#include <functional>
|
|
#include <sys/types.h>
|
|
|
|
namespace FEXCore::Context {
|
|
class Context;
|
|
}
|
|
|
|
namespace FEX::EmulatedFile {
|
|
class EmulatedFDManager {
|
|
public:
|
|
EmulatedFDManager(FEXCore::Context::Context* ctx);
|
|
~EmulatedFDManager();
|
|
int32_t Open(const char* pathname, int flags, uint32_t mode);
|
|
|
|
private:
|
|
FEXCore::Context::Context* CTX;
|
|
fextl::string cpus_online {};
|
|
std::once_flag cpu_info_initialized {};
|
|
fextl::string cpu_info {};
|
|
using FDReadStringFunc = std::function<int32_t(FEXCore::Context::Context* ctx, int32_t fd, const char* pathname, int32_t flags, mode_t mode)>;
|
|
fextl::unordered_map<fextl::string, FDReadStringFunc> FDReadCreators;
|
|
|
|
static int32_t ProcAuxv(FEXCore::Context::Context* ctx, int32_t fd, const char* pathname, int32_t flags, mode_t mode);
|
|
const uint32_t ThreadsConfig;
|
|
};
|
|
} // namespace FEX::EmulatedFile
|