diff options
| author | Stefan Boberg <[email protected]> | 2023-11-21 14:52:56 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-11-21 14:52:56 +0100 |
| commit | 8e1cb139d817880c557d407c363eb838c0893f5a (patch) | |
| tree | 69da94b1df3f2fd1d19e623084c88543c0ce85f6 /src/zencore/process.cpp | |
| parent | basic ZEN_ASSERT_FORMAT implementation (#556) (diff) | |
| download | zen-8e1cb139d817880c557d407c363eb838c0893f5a.tar.xz zen-8e1cb139d817880c557d407c363eb838c0893f5a.zip | |
zen run command (#552)
initial version -- this is primarily intended to be used for running stress tests and/or benchmarks
example usage:
`zen run -n 10 -- zenserver-test`
`zen run -n 10 -- zenserver-test --ts=core.assert` run zenserver-test 10 times (testing only the `core.assert` test suite)
`zen run --time 600 --basepath=d:\test_dir\test1 -- zenserver-test` keeps spawning new instances for 10 minutes (600 seconds)
Diffstat (limited to 'src/zencore/process.cpp')
| -rw-r--r-- | src/zencore/process.cpp | 61 |
1 files changed, 59 insertions, 2 deletions
diff --git a/src/zencore/process.cpp b/src/zencore/process.cpp index 1c208701c..2d0ec2de6 100644 --- a/src/zencore/process.cpp +++ b/src/zencore/process.cpp @@ -185,6 +185,11 @@ ProcessHandle::Wait(int TimeoutMs) int WaitState = 0; waitpid(m_Pid, &WaitState, WNOHANG | WCONTINUED | WUNTRACED); + if (WIFEXITED(WaitState)) + { + m_ExitCode = WEXITSTATUS(WaitState); + } + if (kill(m_Pid, 0) < 0) { int32_t LastError = zen::GetLastError(); @@ -220,6 +225,8 @@ ProcessHandle::WaitExitCode() ZEN_ASSERT(ExitCode != STILL_ACTIVE); return ExitCode; +#elif ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC + return m_ExitCode; #else ZEN_NOT_IMPLEMENTED(); @@ -278,7 +285,7 @@ CreateProcNormal(const std::filesystem::path& Executable, std::string_view Comma PROCESS_INFORMATION ProcessInfo{}; STARTUPINFO StartupInfo{.cb = sizeof(STARTUPINFO)}; - const bool InheritHandles = false; + bool InheritHandles = false; void* Environment = nullptr; LPSECURITY_ATTRIBUTES ProcessAttributes = nullptr; LPSECURITY_ATTRIBUTES ThreadAttributes = nullptr; @@ -298,6 +305,42 @@ CreateProcNormal(const std::filesystem::path& Executable, std::string_view Comma ExtendableWideStringBuilder<256> CommandLineZ; CommandLineZ << CommandLine; + if (!Options.StdoutFile.empty()) + { + SECURITY_ATTRIBUTES sa; + sa.nLength = sizeof sa; + sa.lpSecurityDescriptor = nullptr; + sa.bInheritHandle = TRUE; + + StartupInfo.hStdInput = nullptr; + StartupInfo.hStdOutput = CreateFileW(Options.StdoutFile.c_str(), + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ, + &sa, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + nullptr); + + const BOOL Success = DuplicateHandle(GetCurrentProcess(), + StartupInfo.hStdOutput, + GetCurrentProcess(), + &StartupInfo.hStdError, + 0, + TRUE, + DUPLICATE_SAME_ACCESS); + + if (Success) + { + StartupInfo.dwFlags |= STARTF_USESTDHANDLES; + InheritHandles = true; + } + else + { + CloseHandle(StartupInfo.hStdOutput); + StartupInfo.hStdOutput = 0; + } + } + BOOL Success = CreateProcessW(Executable.c_str(), CommandLineZ.Data(), ProcessAttributes, @@ -309,6 +352,12 @@ CreateProcNormal(const std::filesystem::path& Executable, std::string_view Comma &StartupInfo, &ProcessInfo); + if (StartupInfo.dwFlags & STARTF_USESTDHANDLES) + { + CloseHandle(StartupInfo.hStdError); + CloseHandle(StartupInfo.hStdOutput); + } + if (!Success) { return nullptr; @@ -395,6 +444,14 @@ CreateProcUnelevated(const std::filesystem::path& Executable, std::string_view C ExtendableWideStringBuilder<256> CommandLineZ; CommandLineZ << CommandLine; + ExtendableWideStringBuilder<256> CurrentDirZ; + LPCWSTR WorkingDirectoryPtr = nullptr; + if (Options.WorkingDirectory) + { + CurrentDirZ << Options.WorkingDirectory->native(); + WorkingDirectoryPtr = CurrentDirZ.c_str(); + } + bOk = CreateProcessW(Executable.c_str(), CommandLineZ.Data(), nullptr, @@ -402,7 +459,7 @@ CreateProcUnelevated(const std::filesystem::path& Executable, std::string_view C FALSE, CreateProcFlags, nullptr, - nullptr, + WorkingDirectoryPtr, &StartupInfo.StartupInfo, &ProcessInfo); if (bOk == FALSE) |