#include "../include/Exec.hpp" #include "../include/env.hpp" using namespace std; namespace sibs { #if OS_FAMILY == OS_FAMILY_POSIX Result exec(const _tinydir_char_t *cmd, bool print) { char buffer[128]; std::string result; FILE *pipe = popen(cmd, "r"); if(!pipe) return Result::Err("popen() failed"); while(!feof(pipe)) { if(fgets(buffer, 128, pipe)) { result += buffer; if(print) printf("%s", buffer); } } int processCloseResult = pclose(pipe); if(WIFEXITED(processCloseResult)) { int returned = WEXITSTATUS(processCloseResult); ExecResult execResult; execResult.execStdout = result; execResult.exitCode = returned; return Result::Ok(execResult); } else if(WIFSIGNALED(processCloseResult)) { int signum = WSTOPSIG(processCloseResult); string errMsg = "Exited due to receiving signal "; errMsg += to_string(signum); return Result::Err(errMsg); } else if(WIFSTOPPED(processCloseResult)) { int signum = WSTOPSIG(processCloseResult); string errMsg = "Stopped due to receiving signal "; errMsg += to_string(signum); return Result::Err(errMsg); } else { string errMsg = "exec unexpected error on pclose: "; errMsg += to_string(processCloseResult); return Result::Err(errMsg); } } #else // TODO(Windows): Redirect stdout (and stderr) to string Result exec(const _tinydir_char_t *cmd, bool print) { char buffer[128]; std::string result; STARTUPINFO startupInfo; ZeroMemory(&startupInfo, sizeof(startupInfo)); startupInfo.cb = sizeof(startupInfo); PROCESS_INFORMATION processInfo; ZeroMemory(&processInfo, sizeof(processInfo)); DWORD exitCode; if (!CreateProcess(NULL, (LPWSTR)cmd, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo)) { string errMsg = "exec unexpected error: "; errMsg += toUtf8(getLastErrorAsString()); return Result::Err(errMsg); } WaitForSingleObject(processInfo.hProcess, INFINITE); GetExitCodeProcess(processInfo.hProcess, &exitCode); CloseHandle(processInfo.hProcess); CloseHandle(processInfo.hThread); if (exitCode == 0) { ExecResult execResult; execResult.execStdout = result; execResult.exitCode = exitCode; return Result::Ok(execResult); } else { string errMsg = "Exited with non-zero exit code ("; errMsg += to_string(exitCode); errMsg += "): "; errMsg += toUtf8(getLastErrorAsString()); return Result::Err(errMsg); } } #endif }