From 513abd332c3256774314bba239b956ef03b3f16e Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 29 Jul 2026 20:02:30 +0300 Subject: [PATCH] add platform::new_engine_instance subProcess parameter --- src/logic/scripting/lua/libs/libapp.cpp | 3 +- src/util/platform.cpp | 73 ++++++++++++++++++++++++- src/util/platform.hpp | 4 +- 3 files changed, 77 insertions(+), 3 deletions(-) diff --git a/src/logic/scripting/lua/libs/libapp.cpp b/src/logic/scripting/lua/libs/libapp.cpp index 6442fcbad..12758c724 100644 --- a/src/logic/scripting/lua/libs/libapp.cpp +++ b/src/logic/scripting/lua/libs/libapp.cpp @@ -365,7 +365,8 @@ static int l_start_debug_instance(lua::State* L) { platform::new_engine_instance( std::move(args), - outputPath.empty() ? "" : io::resolve(std::string(outputPath)) + outputPath.empty() ? "" : io::resolve(std::string(outputPath)), + true // debug instance may be detached ); return lua::pushinteger(L, port); } diff --git a/src/util/platform.cpp b/src/util/platform.cpp index f113641e5..76ed8a973 100644 --- a/src/util/platform.cpp +++ b/src/util/platform.cpp @@ -18,7 +18,11 @@ #pragma comment(lib, "winmm.lib") #else #include +#include #include +#include +#include +#include #endif namespace platform::internal { @@ -216,7 +220,9 @@ std::filesystem::path platform::get_executable_path() { } void platform::new_engine_instance( - const std::vector& args, std::filesystem::path outputFile + const std::vector& args, + std::filesystem::path outputFile, + bool subProcess ) { auto executable = get_executable_path(); @@ -285,6 +291,37 @@ void platform::new_engine_instance( &si, &pi ); + if (subProcess) { + HANDLE job = CreateJobObjectW(nullptr, nullptr); + + JOBOBJECT_EXTENDED_LIMIT_INFORMATION info{}; + info.BasicLimitInformation.LimitFlags = + JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + + try { + if (!SetInformationJobObject( + job, + JobObjectExtendedLimitInformation, + &info, + sizeof(info))) { + throw std::runtime_error( + "SetInformationJobObject failed with code: " + + std::to_string(GetLastError()) + ); + } + if (!AssignProcessToJobObject(job, pi.hProcess)) { + throw std::runtime_error( + "SetInformationJobObject failed with code: " + + std::to_string(GetLastError()) + ); + } + } catch (const std::exception& err) { + CloseHandle(job); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + return; + } + } if (success) { CloseHandle(pi.hProcess); CloseHandle(pi.hThread); @@ -295,6 +332,40 @@ void platform::new_engine_instance( ); } #else + + if (subProcess) { + pid_t pid = fork(); + + int fd = open( + outputFile.string().c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0644 + ); + + if (pid == 0) { + prctl(PR_SET_PDEATHSIG, SIGTERM); + + if (getppid() == 1) { + _exit(1); + } + + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + close(fd); + + std::vector argv(args.size() + 2); + argv[0] = const_cast(executable.c_str()); + for (int i = 0; i < args.size(); i++) { + argv[i + 1] = args[i].c_str(); + } + argv[args.size() + 1] = nullptr; + + execvp(executable.c_str(), const_cast(argv.data())); + + _exit(127); + } else { + close(fd); + } + } + std::stringstream ss; ss << executable; for (int i = 0; i < args.size(); i++) { diff --git a/src/util/platform.hpp b/src/util/platform.hpp index 54c56a0c5..2ff535248 100644 --- a/src/util/platform.hpp +++ b/src/util/platform.hpp @@ -19,7 +19,9 @@ namespace platform { std::filesystem::path get_executable_path(); /// @brief Run a separate engine instance with specified arguments void new_engine_instance( - const std::vector& args, std::filesystem::path outputFile + const std::vector& args, + std::filesystem::path outputFile, + bool subProcess ); /// @brief Open URL in web browser bool open_url(const std::string& url);