From da245b60e31ad9c9374d84eaafaeba24c5aa13c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dar=C3=ADo?= Date: Tue, 17 Dec 2024 15:09:45 -0300 Subject: [PATCH] Implement OS Restart on Linux. (#50) --- UnleashedRecomp/os/linux/process_linux.cpp | 51 +++++++++++++++++++--- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/UnleashedRecomp/os/linux/process_linux.cpp b/UnleashedRecomp/os/linux/process_linux.cpp index 8a8dae42..ed02c9e9 100644 --- a/UnleashedRecomp/os/linux/process_linux.cpp +++ b/UnleashedRecomp/os/linux/process_linux.cpp @@ -1,20 +1,57 @@ #include +#include + std::filesystem::path os::process::detail::GetExecutablePath() { - assert(false && "Unimplemented."); - return std::filesystem::path(); + char exePath[PATH_MAX] = {}; + if (readlink("/proc/self/exe", exePath, PATH_MAX) > 0) + { + return std::filesystem::path(std::u8string_view((const char8_t*)(exePath))); + } + else + { + return std::filesystem::path(); + } } std::filesystem::path os::process::detail::GetWorkingDirectory() { - // TODO: There's a cross platform way to retrieve this which is just getting it from argv[0]. - assert(false && "Unimplemented."); - return std::filesystem::path(); + char cwd[PATH_MAX] = {}; + char *res = getcwd(cwd, sizeof(cwd)); + if (res != nullptr) + { + return std::filesystem::path(std::u8string_view((const char8_t*)(cwd))); + } + else + { + return std::filesystem::path(); + } } bool os::process::detail::StartProcess(const std::filesystem::path path, const std::vector args, std::filesystem::path work) { - assert(false && "Unimplemented."); - return false; + pid_t pid = fork(); + if (pid < 0) + return false; + + if (pid == 0) + { + setsid(); + + std::u8string workU8 = work.u8string(); + chdir((const char*)(workU8.c_str())); + + std::u8string pathU8 = path.u8string(); + std::vector argStrs; + argStrs.push_back((char*)(pathU8.c_str())); + for (const std::string& arg : args) + argStrs.push_back((char *)(arg.c_str())); + + argStrs.push_back(nullptr); + execvp((const char*)(pathU8.c_str()), argStrs.data()); + raise(SIGKILL); + } + + return true; }