137 lines
4.3 KiB
C++
137 lines
4.3 KiB
C++
|
DQN_API void Dqn_OS_Exit(uint32_t exit_code)
|
||
|
{
|
||
|
#if defined(DQN_OS_WIN32)
|
||
|
ExitProcess(exit_code);
|
||
|
#else
|
||
|
exit(exit_code);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
// NOTE: [$EXEC] Dqn_OSExec ========================================================================
|
||
|
DQN_API Dqn_OSExecResult Dqn_OS_ExecWait(Dqn_OSExecAsyncHandle handle)
|
||
|
{
|
||
|
Dqn_OSExecResult result = {};
|
||
|
if (!handle.process || handle.os_error_code) {
|
||
|
result.os_error_code = handle.os_error_code;
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
#if defined(DQN_OS_WIN32)
|
||
|
DWORD exec_result = WaitForSingleObject(handle.process, INFINITE);
|
||
|
if (exec_result == WAIT_FAILED) {
|
||
|
result.os_error_code = GetLastError();
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
DWORD exit_status;
|
||
|
if (!GetExitCodeProcess(handle.process, &exit_status)) {
|
||
|
result.os_error_code = GetLastError();
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
result.exit_code = exit_status;
|
||
|
CloseHandle(handle.process);
|
||
|
#elif defined(DQN_PLATFORM_EMSCRIPTEN)
|
||
|
DQN_ASSERTF(false, "Unsupported operation");
|
||
|
#else
|
||
|
for (;;) {
|
||
|
int status = 0;
|
||
|
if (waitpid(DQN_CAST(pid_t)handle.process, &status, 0) < 0) {
|
||
|
result.os_error_code = errno;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (WIFEXITED(status)) {
|
||
|
result.exit_code = WEXITSTATUS(status);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (WIFSIGNALLED(status)) {
|
||
|
result.os_error_code = WTERMSIG(status);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
DQN_API Dqn_OSExecAsyncHandle Dqn_OS_ExecAsync(Dqn_Str8 cmd, Dqn_Str8 working_dir)
|
||
|
{
|
||
|
Dqn_OSExecAsyncHandle result = {};
|
||
|
if (cmd.size == 0)
|
||
|
return result;
|
||
|
|
||
|
#if defined(DQN_OS_WIN32)
|
||
|
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
|
||
|
Dqn_Str16 cmd16 = Dqn_Win_Str8ToStr16(scratch.arena, cmd);
|
||
|
Dqn_Str16 working_dir16 = Dqn_Win_Str8ToStr16(scratch.arena, working_dir);
|
||
|
|
||
|
PROCESS_INFORMATION proc_info = {};
|
||
|
STARTUPINFOW startup_info = {};
|
||
|
startup_info.cb = sizeof(STARTUPINFOW);
|
||
|
startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
|
||
|
startup_info.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
|
||
|
startup_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
|
||
|
startup_info.dwFlags |= STARTF_USESTDHANDLES;
|
||
|
BOOL create_result = CreateProcessW(nullptr, cmd16.data, nullptr, nullptr, true, 0, nullptr, working_dir16.data, &startup_info, &proc_info);
|
||
|
if (!create_result) {
|
||
|
result.os_error_code = GetLastError();
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
CloseHandle(proc_info.hThread);
|
||
|
result.process = proc_info.hProcess;
|
||
|
#else
|
||
|
DQN_ASSERTF(false, "Unsupported operation");
|
||
|
// TODO: This API will need to switch to an array of strings for unix
|
||
|
#if 0
|
||
|
pid_t child_pid = fork();
|
||
|
if (child_pid < 0) {
|
||
|
result.os_error_code = errno;
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
if (child_pid == 0) {
|
||
|
if (working_dir.size) {
|
||
|
if (chdir(working_dir.data) == -1) {
|
||
|
result.os_error_code = errno;
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (execvp(cmd.items[0], (char * const*) cmd_null.items) < 0) {
|
||
|
result.os_error_code = errno;
|
||
|
return result;
|
||
|
}
|
||
|
DQN_INVALID_CODE_PATH;
|
||
|
}
|
||
|
|
||
|
result.process = DQN_CAST(void *)child_pid;
|
||
|
#endif
|
||
|
#endif
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
DQN_API Dqn_OSExecResult Dqn_OS_Exec(Dqn_Str8 cmd, Dqn_Str8 working_dir)
|
||
|
{
|
||
|
Dqn_OSExecAsyncHandle async_handle = Dqn_OS_ExecAsync(cmd, working_dir);
|
||
|
Dqn_OSExecResult result = Dqn_OS_ExecWait(async_handle);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
DQN_API void Dqn_OS_ExecOrAbort(Dqn_Str8 cmd, Dqn_Str8 working_dir)
|
||
|
{
|
||
|
Dqn_OSExecResult result = Dqn_OS_Exec(cmd, working_dir);
|
||
|
if (result.os_error_code || result.exit_code) {
|
||
|
if (result.os_error_code) {
|
||
|
Dqn_Log_ErrorF("OS failed to execute the requested command returning the error code %u. The command was\n\n%.*s", result.os_error_code, DQN_STR_FMT(cmd));
|
||
|
Dqn_OS_Exit(result.os_error_code);
|
||
|
}
|
||
|
|
||
|
if (result.exit_code) {
|
||
|
Dqn_Log_ErrorF("OS executed command and returned a non-zero status: %u. The command was\n\n%.*s", result.exit_code, DQN_STR_FMT(cmd));
|
||
|
Dqn_OS_Exit(result.exit_code);
|
||
|
}
|
||
|
}
|
||
|
}
|