mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-08 12:00:17 +02:00
This is a relatively invasive change since multiple things needed to
happen at once.
* Socket based logging is removed
* Logging has been replaced to only support stdout, stderr, and server
* Server is now default and replaces what FEXLogServer did
* Server logging now uses a pipe instead of a socket
* Can be faster than stderr and stdout since the application doesn't
need to wait on terminal output
* FEXMountDaemon has been removed
* Functionality has been merged in to FEXServer
* FEXServer is always executed on FEX initialization time
* Similar in behaviour to Wine's wineserver
* Can explicitly start this before using FEX for logging purposes
* Stays around until all instances of FEX exit
* Will stick around for a short amount of time in case of spurious
execution
* FEXServer will soon be extended to do more than logging and squashfs
mounting
* FEX rootfs scripts will need to be updated to support this path
* Just means rbinding the /tmp folder and forcing a FEXServer instance
to be alive
* Pressure-vessel works fine in this case since FEXServer will already
be running
* It already rbinds the host /tmp folder which is why this works
109 lines
3.2 KiB
C++
109 lines
3.2 KiB
C++
/*
|
|
$info$
|
|
tags: Bin|FEXBash
|
|
desc: Launches bash under FEX and passes arguments via -c to it
|
|
$end_info$
|
|
*/
|
|
|
|
#include "ConfigDefines.h"
|
|
#include "Common/ArgumentLoader.h"
|
|
#include "Common/FEXServerClient.h"
|
|
|
|
#include <FEXCore/Config/Config.h>
|
|
#include <FEXCore/Utils/LogManager.h>
|
|
|
|
#include <filesystem>
|
|
#include <iterator>
|
|
#include <memory>
|
|
#include <stddef.h>
|
|
#include <string>
|
|
#include <unistd.h>
|
|
#include <vector>
|
|
|
|
int main(int argc, char **argv, char **const envp) {
|
|
FEXCore::Config::Initialize();
|
|
FEXCore::Config::AddLayer(FEXCore::Config::CreateMainLayer());
|
|
FEX::ArgLoader::LoadWithoutArguments(argc, argv);
|
|
FEXCore::Config::AddLayer(FEXCore::Config::CreateEnvironmentLayer(envp));
|
|
FEXCore::Config::Load();
|
|
|
|
// Reload the meta layer
|
|
FEXCore::Config::ReloadMetaLayer();
|
|
|
|
auto Args = FEX::ArgLoader::Get();
|
|
|
|
// Ensure FEXServer is setup before config options try to pull CONFIG_ROOTFS
|
|
if (!FEXServerClient::SetupClient(argv[0])) {
|
|
LogMan::Msg::EFmt("FEXServerClient: Failure to setup client");
|
|
return -1;
|
|
}
|
|
|
|
FEX_CONFIG_OPT(RootFSPath, ROOTFS);
|
|
std::vector<const char*> Argv;
|
|
std::string BinShPath = RootFSPath() + "/bin/sh";
|
|
std::string BinBashPath = RootFSPath() + "/bin/bash";
|
|
|
|
std::string FEXInterpreterPath = std::filesystem::path(argv[0]).parent_path().string() + "FEXInterpreter";
|
|
// Check if a local FEXInterpreter to FEXBash exists
|
|
// If it does then it takes priority over the installed one
|
|
if (!std::filesystem::exists(FEXInterpreterPath)) {
|
|
FEXInterpreterPath = FEXCore::Config::FindContainerPrefix() + FEXINTERPRETER_PATH;
|
|
}
|
|
const char *FEXArgs[] = {
|
|
FEXInterpreterPath.c_str(),
|
|
Args.empty() ? BinBashPath.c_str() : BinShPath.c_str(),
|
|
"-c",
|
|
};
|
|
|
|
// Remove -c argument if arguments are empty
|
|
// Lets us start an emulated bash instance
|
|
const size_t FEXArgsCount = std::size(FEXArgs) - (Args.empty() ? 1 : 0);
|
|
|
|
Argv.resize(Args.size() + FEXArgsCount);
|
|
|
|
// Pass in the FEXInterpreter arguments
|
|
for (size_t i = 0; i < FEXArgsCount; ++i) {
|
|
Argv[i] = FEXArgs[i];
|
|
}
|
|
|
|
// Bring in passed in arguments
|
|
for (size_t i = 0; i < Args.size(); ++i) {
|
|
Argv[i + FEXArgsCount] = Args[i].c_str();
|
|
}
|
|
|
|
// Set --norc when no arguments are passed so PS1 doesn't get overwritten
|
|
const char* NoRC = "--norc";
|
|
if (Args.empty()) {
|
|
Argv.emplace_back(NoRC);
|
|
}
|
|
|
|
Argv.emplace_back(nullptr);
|
|
|
|
// Prepend `FEXBash>` to PS1 to be less confusing about running under emulation
|
|
// In most cases PS1 isn't an environment variable, but instead a shell variable
|
|
// But in case the user has set the PS1 environment variable then still prepend
|
|
//
|
|
// To get the shell variables as an environment variable then you can do `PS1=$PS1 FEXBash`
|
|
std::vector<const char *> Envp{};
|
|
char *PS1Env{};
|
|
for (unsigned i = 0;; ++i) {
|
|
if (envp[i] == nullptr)
|
|
break;
|
|
if (strstr(envp[i], "PS1=") == envp[i]) {
|
|
PS1Env = envp[i];
|
|
}
|
|
else {
|
|
Envp.emplace_back(envp[i]);
|
|
}
|
|
}
|
|
|
|
std::string PS1 = "PS1=FEXBash> ";
|
|
if (PS1Env) {
|
|
PS1 += &PS1Env[strlen("PS1=")];
|
|
}
|
|
Envp.emplace_back(PS1.c_str());
|
|
Envp.emplace_back(nullptr);
|
|
|
|
return execve(Argv[0], const_cast<char *const*>(&Argv.at(0)), const_cast<char *const*>(&Envp[0]));
|
|
}
|