#include #include #include #include #include #include #include #include #ifdef _WIN32 #include #endif namespace Cli { int Autorun(const std::string& absPath, bool toWindows) { if (!toWindows) { std::filesystem::permissions(Io::NativePath(absPath), std::filesystem::perms::owner_exec | std::filesystem::perms::group_exec | std::filesystem::perms::others_exec, std::filesystem::perm_options::add); } int rawCode = 0; int exitCode = 0; #ifdef _WIN32 std::wstring command = L"\"" + Io::NativePath(absPath).wstring() + L"\""; STARTUPINFOW startup{}; startup.cb = sizeof(startup); PROCESS_INFORMATION process{}; if (!CreateProcessW(nullptr, command.data(), nullptr, nullptr, FALSE, 0, nullptr, nullptr, &startup, &process)) throw Domain::RelinkerException("Cannot run the output executable: " + absPath); if (WaitForSingleObject(process.hProcess, INFINITE) != WAIT_OBJECT_0) { const unsigned long waitError = GetLastError(); CloseHandle(process.hThread); CloseHandle(process.hProcess); throw Domain::RelinkerException("Cannot wait for the output executable: " + absPath + " (error " + std::to_string(waitError) + ")"); } unsigned long rawExitCode = 0; if (!GetExitCodeProcess(process.hProcess, &rawExitCode)) { const unsigned long exitError = GetLastError(); CloseHandle(process.hThread); CloseHandle(process.hProcess); throw Domain::RelinkerException("Cannot read the output executable exit code: " + absPath + " (error " + std::to_string(exitError) + ")"); } CloseHandle(process.hThread); CloseHandle(process.hProcess); rawCode = static_cast(rawExitCode); exitCode = rawCode; std::cout << "\nExit code: " << rawCode << '\n'; #else std::string cmd = "'"; for (const char character : absPath) { if (character == '\'') cmd += "'\\''"; else cmd += character; } cmd += '\''; rawCode = std::system(cmd.c_str()); if (rawCode != -1) { const int signal = rawCode & 0x7F; exitCode = signal ? 128 + signal : (rawCode >> 8) & 0xFF; } std::cout << "\nRaw exit code: " << rawCode << "; Unpacked: " << exitCode << '\n'; #endif std::cout << "\nPress Enter to exit...\n"; std::cin.ignore(std::numeric_limits::max(), '\n'); return exitCode; } }