Merge pull request #4331 from Sonicadvance1/fix_portable_fexserver

FEXServer: Fixes FEX_PORTABLE usage
This commit is contained in:
Ryan Houdek authored and GitHub committed 2025-02-07 12:15:58 -08:00
commit ee47b5bbc9
5 files changed
+54 -37

No files matched your search

+16 -6
View File
@@ -334,9 +334,14 @@ void ReloadMetaLayer() {
FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_ROOTFS, ExpandedString);
} else if (!PathName->empty()) {
// If the filesystem doesn't exist then let's see if it exists in the fex-emu folder
fextl::string NamedRootFS = GetDataDirectory(false) + "RootFS/" + *PathName;
if (FHU::Filesystem::Exists(NamedRootFS)) {
FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_ROOTFS, NamedRootFS);
const auto PathNameCopy = *PathName;
for (auto Global : {true, false}) {
for (auto DirectoryFetchers : {GetDataDirectory, GetConfigDirectory}) {
fextl::string NamedRootFS = DirectoryFetchers(Global) + "RootFS/" + PathNameCopy;
if (FHU::Filesystem::Exists(NamedRootFS)) {
FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_ROOTFS, NamedRootFS);
}
}
}
}
}
@@ -356,9 +361,14 @@ void ReloadMetaLayer() {
FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_THUNKCONFIG, ExpandedString);
} else if (!PathName->empty()) {
// If the filesystem doesn't exist then let's see if it exists in the fex-emu folder
fextl::string NamedConfig = GetDataDirectory(false) + "ThunkConfigs/" + *PathName;
if (FHU::Filesystem::Exists(NamedConfig)) {
FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_THUNKCONFIG, NamedConfig);
const auto PathNameCopy = *PathName;
for (auto Global : {true, false}) {
for (auto DirectoryFetchers : {GetDataDirectory, GetConfigDirectory}) {
fextl::string NamedConfig = DirectoryFetchers(Global) + "ThunkConfigs/" + PathNameCopy;
if (FHU::Filesystem::Exists(NamedConfig)) {
FEXCore::Config::EraseSet(FEXCore::Config::CONFIG_THUNKCONFIG, NamedConfig);
}
}
}
}
}
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: MIT
#pragma once
#include "Common/Config.h"
namespace FEX {
static inline FEX::Config::PortableInformation ReadPortabilityInformation() {
const FEX::Config::PortableInformation BadResult {false, {}};
const char* PortableConfig = getenv("FEX_PORTABLE");
if (!PortableConfig) {
return BadResult;
}
uint32_t Value {};
std::string_view PortableView {PortableConfig};
if (std::from_chars(PortableView.data(), PortableView.data() + PortableView.size(), Value).ec != std::errc {} || Value == 0) {
return BadResult;
}
// Read the FEXInterpreter path from `/proc/self/exe` which is always a symlink to the absolute path of the executable running.
// This way we can get the parent path that the application is executing from.
char SelfPath[PATH_MAX];
auto Result = readlink("/proc/self/exe", SelfPath, PATH_MAX);
if (Result == -1) {
return BadResult;
}
std::string_view SelfPathView {SelfPath, std::min<size_t>(PATH_MAX, Result)};
// Extract the absolute path from the FEXInterpreter path
return {true, fextl::string {SelfPathView.substr(0, SelfPathView.find_last_of('/') + 1)}};
}
} // namespace FEX
+2 -29
View File
@@ -11,6 +11,7 @@ $end_info$
#include "Common/FEXServerClient.h"
#include "Common/Config.h"
#include "Common/HostFeatures.h"
#include "PortabilityInfo.h"
#include "ELFCodeLoader.h"
#include "VDSO_Emulation.h"
#include "LinuxSyscalls/GdbServer.h"
@@ -176,34 +177,6 @@ bool InterpreterHandler(fextl::string* Filename, const fextl::string& RootFS, fe
return true;
}
FEX::Config::PortableInformation ReadPortabilityInformation() {
const FEX::Config::PortableInformation BadResult {false, {}};
const char* PortableConfig = getenv("FEX_PORTABLE");
if (!PortableConfig) {
return BadResult;
}
uint32_t Value {};
std::string_view PortableView {PortableConfig};
if (std::from_chars(PortableView.data(), PortableView.data() + PortableView.size(), Value).ec != std::errc {} || Value == 0) {
return BadResult;
}
// Read the FEXInterpreter path from `/proc/self/exe` which is always a symlink to the absolute path of the executable running.
// This way we can get the parent path that the application is executing from.
char SelfPath[PATH_MAX];
auto Result = readlink("/proc/self/exe", SelfPath, PATH_MAX);
if (Result == -1) {
return BadResult;
}
std::string_view SelfPathView {SelfPath, std::min<size_t>(PATH_MAX, Result)};
// Extract the absolute path from the FEXInterpreter path
return {true, fextl::string {SelfPathView.substr(0, SelfPathView.find_last_of('/') + 1)}};
}
bool RanAsInterpreter(bool ExecutedWithFD) {
return ExecutedWithFD || FEXLOADER_AS_INTERPRETER;
}
@@ -323,7 +296,7 @@ int main(int argc, char** argv, char** const envp) {
const bool ExecutedWithFD = getauxval(AT_EXECFD) != 0;
const bool IsInterpreter = RanAsInterpreter(ExecutedWithFD);
const auto PortableInfo = ReadPortabilityInformation();
const auto PortableInfo = FEX::ReadPortabilityInformation();
const bool InterpreterInstalled = QueryInterpreterInstalled(ExecutedWithFD, PortableInfo);
int FEXFD {StealFEXFDFromEnv("FEX_EXECVEFD")};
+1 -1
View File
@@ -12,7 +12,7 @@ target_include_directories(${NAME} PRIVATE
${CMAKE_BINARY_DIR}/generated
${CMAKE_SOURCE_DIR}/Source/)
target_link_libraries(${NAME} PRIVATE FEXCore Common JemallocDummy ${PTHREAD_LIB})
target_link_libraries(${NAME} PRIVATE FEXCore Common CommonTools JemallocDummy ${PTHREAD_LIB})
if (CMAKE_BUILD_TYPE MATCHES "RELEASE")
target_link_options(${NAME}
+2 -1
View File
@@ -2,6 +2,7 @@
#include "ArgumentLoader.h"
#include "Logger.h"
#include "PipeScanner.h"
#include "PortabilityInfo.h"
#include "ProcessPipe.h"
#include "SquashFS.h"
#include "Common/ArgumentLoader.h"
@@ -117,7 +118,7 @@ int main(int argc, char** argv, char** const envp) {
}
auto ArgsLoader = fextl::make_unique<FEX::ArgLoader::ArgLoader>(FEX::ArgLoader::ArgLoader::LoadType::WITHOUT_FEXLOADER_PARSER, argc, argv);
FEX::Config::LoadConfig(std::move(ArgsLoader), {}, envp);
FEX::Config::LoadConfig(std::move(ArgsLoader), {}, envp, FEX::ReadPortabilityInformation());
// Reload the meta layer
FEXCore::Config::ReloadMetaLayer();