1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include <zencore/thread.h>
#include <zencore/zencore.h>
#include <filesystem>
namespace zen {
/** Basic process abstraction
*/
class ProcessHandle
{
public:
ZENCORE_API ProcessHandle();
ProcessHandle(const ProcessHandle&) = delete;
ProcessHandle& operator=(const ProcessHandle&) = delete;
ZENCORE_API ~ProcessHandle();
ZENCORE_API void Initialize(int Pid);
ZENCORE_API void Initialize(int Pid, std::error_code& OutEc);
ZENCORE_API void Initialize(void* ProcessHandle); /// Initialize with an existing handle - takes ownership of the handle
ZENCORE_API [[nodiscard]] bool IsRunning() const;
ZENCORE_API [[nodiscard]] bool IsValid() const;
ZENCORE_API bool Wait(int TimeoutMs = -1);
ZENCORE_API bool Wait(int TimeoutMs, std::error_code& OutEc);
ZENCORE_API int WaitExitCode();
ZENCORE_API int GetExitCode();
ZENCORE_API bool Terminate(int ExitCode);
ZENCORE_API void Reset();
[[nodiscard]] inline int Pid() const { return m_Pid; }
private:
void* m_ProcessHandle = nullptr;
int m_Pid = 0;
#if ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC
int m_ExitCode = -1;
#endif
};
/** Basic process creation
*/
struct CreateProcOptions
{
enum
{
Flag_NewConsole = 1 << 0,
Flag_Elevated = 1 << 1,
Flag_Unelevated = 1 << 2,
Flag_NoConsole = 1 << 3,
};
const std::filesystem::path* WorkingDirectory = nullptr;
uint32_t Flags = 0;
std::filesystem::path StdoutFile;
};
#if ZEN_PLATFORM_WINDOWS
using CreateProcResult = void*; // handle to the process
#else
using CreateProcResult = int32_t; // pid
#endif
ZENCORE_API CreateProcResult CreateProc(const std::filesystem::path& Executable,
std::string_view CommandLine, // should also include arg[0] (executable name)
const CreateProcOptions& Options = {});
/** Process monitor - monitors a list of running processes via polling
Intended to be used to monitor a set of "sponsor" processes, where
we need to determine when none of them remain alive
*/
class ProcessMonitor
{
public:
ProcessMonitor();
~ProcessMonitor();
ZENCORE_API bool IsRunning();
ZENCORE_API void AddPid(int Pid);
ZENCORE_API bool IsActive() const;
private:
using HandleType = void*;
mutable RwLock m_Lock;
std::vector<HandleType> m_ProcessHandles;
};
ZENCORE_API bool IsProcessRunning(int pid);
ZENCORE_API bool IsProcessRunning(int pid, std::error_code& OutEc);
ZENCORE_API int GetCurrentProcessId();
int GetProcessId(CreateProcResult ProcId);
std::filesystem::path GetProcessExecutablePath(int Pid, std::error_code& OutEc);
std::error_code FindProcess(const std::filesystem::path& ExecutableImage, ProcessHandle& OutHandle);
void process_forcelink(); // internal
} // namespace zen
|