mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-07 13:00:15 +02:00
Currently FEXBash only outputs `FEXBash>` which gives weird docker vibes. This can confuse users since they no longer see what folder they are in. Change this so it still has the user and path exposed like a typical PS1 eg: `FEXBash-ryanh@ryanh-TR2:/mnt/Work/Work/work/FEXNew/Build>`
110 lines
3.3 KiB
C++
110 lines
3.3 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::CreateGlobalMainLayer());
|
|
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-\\u@\\h:\\w> ";
|
|
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]));
|
|
}
|