refactor process manipulation API
This commit is contained in:
parent
fc3cac5da3
commit
c236b4eaaf
22
src/raylib.h
22
src/raylib.h
|
|
@ -963,10 +963,20 @@ typedef enum {
|
||||||
|
|
||||||
// Process info
|
// Process info
|
||||||
typedef struct Process {
|
typedef struct Process {
|
||||||
int pid; // Process unique identifier
|
int pid; // Process unique identifier
|
||||||
int exitCode; // Process exit code
|
|
||||||
} Process;
|
} Process;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PROCESS_STATE_NONE = 0, // No state information
|
||||||
|
PROCESS_STATE_RUNNING, // Process is running
|
||||||
|
PROCESS_STATE_FINISHED // Process has exited
|
||||||
|
} ProcessState;
|
||||||
|
|
||||||
|
typedef struct ProcessInfo {
|
||||||
|
ProcessState state; // Process state (PROCESS_STATE_*)
|
||||||
|
int exitCode; // Process exit code (if finished)
|
||||||
|
} ProcessInfo;
|
||||||
|
|
||||||
// Callbacks to hook some internal functions
|
// Callbacks to hook some internal functions
|
||||||
// WARNING: These callbacks are intended for advanced users
|
// WARNING: These callbacks are intended for advanced users
|
||||||
typedef void (*TraceLogCallback)(int logLevel, const char *text, va_list args); // Logging: Redirect trace log messages
|
typedef void (*TraceLogCallback)(int logLevel, const char *text, va_list args); // Logging: Redirect trace log messages
|
||||||
|
|
@ -1249,10 +1259,10 @@ RLAPI int GetTouchPointCount(void); // Get number of t
|
||||||
|
|
||||||
// Process execution functions
|
// Process execution functions
|
||||||
RLAPI Process InitProcess(const char *command, char *const args[]); // Initialize a new process, returns a Process struct
|
RLAPI Process InitProcess(const char *command, char *const args[]); // Initialize a new process, returns a Process struct
|
||||||
RLAPI bool CheckProcess(Process *process); // Check if a process is still running, updates Process struct
|
RLAPI ProcessInfo CheckProcess(Process process); // Check if a process is still running
|
||||||
RLAPI void PauseProcess(Process *process); // Pause process execution
|
RLAPI void PauseProcess(Process process); // Pause process execution
|
||||||
RLAPI void ResumeProcess(Process *process); // Resume paused process execution
|
RLAPI void ResumeProcess(Process process); // Resume paused process execution
|
||||||
RLAPI void CloseProcess(Process *process); // Close process and free resources
|
RLAPI void CloseProcess(Process process); // Close process and free resources
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Gestures and Touch Handling Functions (Module: rgestures)
|
// Gestures and Touch Handling Functions (Module: rgestures)
|
||||||
|
|
|
||||||
103
src/rcore.c
103
src/rcore.c
|
|
@ -4345,76 +4345,93 @@ RLAPI Process InitProcess(const char *command, char *const args[])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a process is still running, updates Process struct
|
// Check if a process is still running, updates Process struct
|
||||||
RLAPI bool CheckProcess(Process *process)
|
RLAPI ProcessInfo CheckProcess(Process process)
|
||||||
{
|
{
|
||||||
if ((process == NULL) || (process->pid <= 0))
|
ProcessInfo info = { 0 };
|
||||||
|
|
||||||
|
if (process.pid <= 0)
|
||||||
{
|
{
|
||||||
return false;
|
info.state = PROCESS_STATE_NONE;
|
||||||
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
// PROCESS_QUERY_INFORMATION
|
// PROCESS_QUERY_INFORMATION
|
||||||
void *hProcess = OpenProcess(0x0400, 0, (unsigned long)process->pid);
|
void *hProcess = OpenProcess(0x0400, 0, (unsigned long)process.pid);
|
||||||
if (hProcess == NULL) return false;
|
if (hProcess == NULL)
|
||||||
|
{
|
||||||
|
// Process does not exist
|
||||||
|
info.state = PROCESS_STATE_NONE;
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned long exitCode = 0;
|
unsigned long exitCode = 0;
|
||||||
if (GetExitCodeProcess(hProcess, &exitCode))
|
if (GetExitCodeProcess(hProcess, &exitCode))
|
||||||
{
|
{
|
||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
// STILL_ACTIVE (259) means the process is still running
|
// STILL_ACTIVE (259) means the process is still running
|
||||||
if (exitCode == 259) return true;
|
if (exitCode == 259)
|
||||||
|
{
|
||||||
process->exitCode = (int)exitCode;
|
info.state = PROCESS_STATE_RUNNING;
|
||||||
process->pid = 0;
|
return info;
|
||||||
return false;
|
}
|
||||||
|
|
||||||
|
info.state = PROCESS_STATE_FINISHED;
|
||||||
|
info.exitCode = (int)exitCode;
|
||||||
|
|
||||||
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
return false;
|
|
||||||
|
// If GetExitCodeProcess fails, we consider the process state as unknown
|
||||||
|
info.state = PROCESS_STATE_NONE;
|
||||||
|
return info;
|
||||||
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
|
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
|
||||||
int status = 0;
|
int status = 0;
|
||||||
pid_t result = waitpid(process->pid, &status, WNOHANG);
|
pid_t result = waitpid(process.pid, &status, WNOHANG);
|
||||||
|
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
{
|
{
|
||||||
// Still running
|
// Still running
|
||||||
return true;
|
info.state = PROCESS_STATE_RUNNING;
|
||||||
|
return info;
|
||||||
}
|
}
|
||||||
else if (result == process->pid)
|
else if (result == process.pid)
|
||||||
{
|
{
|
||||||
// Not running
|
// Not running
|
||||||
if (WIFEXITED(status))
|
if (WIFEXITED(status))
|
||||||
{
|
{
|
||||||
process->exitCode = WEXITSTATUS(status);
|
// Normal exit
|
||||||
|
info.state = PROCESS_STATE_FINISHED;
|
||||||
|
info.exitCode = WEXITSTATUS(status);
|
||||||
}
|
}
|
||||||
else if (WIFSIGNALED(status))
|
else if (WIFSIGNALED(status))
|
||||||
{
|
{
|
||||||
// Terminated by signal
|
// Terminated by signal
|
||||||
process->exitCode = -1;
|
info.state = PROCESS_STATE_FINISHED;
|
||||||
|
info.exitCode = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark as completed
|
return info;
|
||||||
process->pid = 0;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Error occurred
|
// Error occurred
|
||||||
TRACELOG(LOG_WARNING, "PROCESS: Failed to check process status");
|
info.state = PROCESS_STATE_NONE;
|
||||||
return false;
|
return info;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
TRACELOG(LOG_WARNING, "PROCESS: Process management not supported on this platform");
|
TRACELOG(LOG_WARNING, "PROCESS: Process management not supported on this platform");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return false;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pause process execution
|
// Pause process execution
|
||||||
RLAPI void PauseProcess(Process *process)
|
RLAPI void PauseProcess(Process process)
|
||||||
{
|
{
|
||||||
if ((process == NULL) || (process->pid <= 0))
|
if (process.pid <= 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -4440,7 +4457,7 @@ RLAPI void PauseProcess(Process *process)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PROCESS_SUSPEND_RESUME
|
// PROCESS_SUSPEND_RESUME
|
||||||
void *hProcess = OpenProcess(0x0800, 0, (unsigned long)process->pid);
|
void *hProcess = OpenProcess(0x0800, 0, (unsigned long)process.pid);
|
||||||
if (hProcess == NULL) {
|
if (hProcess == NULL) {
|
||||||
TRACELOG(LOG_WARNING, "PROCESS: Failed to open process handle");
|
TRACELOG(LOG_WARNING, "PROCESS: Failed to open process handle");
|
||||||
return;
|
return;
|
||||||
|
|
@ -4452,7 +4469,7 @@ RLAPI void PauseProcess(Process *process)
|
||||||
}
|
}
|
||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
|
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
|
||||||
if (kill(process->pid, SIGSTOP) != 0)
|
if (kill(process.pid, SIGSTOP) != 0)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "PROCESS: Failed to pause process");
|
TRACELOG(LOG_WARNING, "PROCESS: Failed to pause process");
|
||||||
}
|
}
|
||||||
|
|
@ -4462,9 +4479,9 @@ RLAPI void PauseProcess(Process *process)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resume paused process execution
|
// Resume paused process execution
|
||||||
RLAPI void ResumeProcess(Process *process)
|
RLAPI void ResumeProcess(Process process)
|
||||||
{
|
{
|
||||||
if ((process == NULL) || (process->pid <= 0))
|
if (process.pid <= 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -4491,7 +4508,7 @@ RLAPI void ResumeProcess(Process *process)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PROCESS_SUSPEND_RESUME
|
// PROCESS_SUSPEND_RESUME
|
||||||
void *hProcess = OpenProcess(0x0800, 0, (unsigned long)process->pid);
|
void *hProcess = OpenProcess(0x0800, 0, (unsigned long)process.pid);
|
||||||
if (hProcess == NULL)
|
if (hProcess == NULL)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "PROCESS: Failed to open process handle");
|
TRACELOG(LOG_WARNING, "PROCESS: Failed to open process handle");
|
||||||
|
|
@ -4504,7 +4521,7 @@ RLAPI void ResumeProcess(Process *process)
|
||||||
}
|
}
|
||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
|
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
|
||||||
if (kill(process->pid, SIGCONT) != 0)
|
if (kill(process.pid, SIGCONT) != 0)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "PROCESS: Failed to resume process");
|
TRACELOG(LOG_WARNING, "PROCESS: Failed to resume process");
|
||||||
}
|
}
|
||||||
|
|
@ -4514,15 +4531,15 @@ RLAPI void ResumeProcess(Process *process)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close process and free resources
|
// Close process and free resources
|
||||||
RLAPI void CloseProcess(Process *process)
|
RLAPI void CloseProcess(Process process)
|
||||||
{
|
{
|
||||||
if ((process == NULL) || (process->pid <= 0))
|
if (process.pid <= 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
// PROCESS_TERMINATE
|
// PROCESS_TERMINATE
|
||||||
void *hProcess = OpenProcess(0x0001, 0, (unsigned long)process->pid);
|
void *hProcess = OpenProcess(0x0001, 0, (unsigned long)process.pid);
|
||||||
if (hProcess == NULL)
|
if (hProcess == NULL)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "PROCESS: Failed to open process handle");
|
TRACELOG(LOG_WARNING, "PROCESS: Failed to open process handle");
|
||||||
|
|
@ -4532,31 +4549,27 @@ RLAPI void CloseProcess(Process *process)
|
||||||
TerminateProcess(hProcess, 0);
|
TerminateProcess(hProcess, 0);
|
||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
|
|
||||||
process->exitCode = -1;
|
|
||||||
process->pid = 0;
|
|
||||||
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
|
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
|
||||||
if (!CheckProcess(process))
|
// If process is not running or not found, nothing to do
|
||||||
|
ProcessInfo info = CheckProcess(process);
|
||||||
|
if (info.state != PROCESS_STATE_RUNNING)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// In case that the process is paused
|
// In case that the process is paused
|
||||||
kill(process->pid, SIGCONT);
|
kill(process.pid, SIGCONT);
|
||||||
|
|
||||||
if (kill(process->pid, SIGTERM) != 0)
|
if (kill(process.pid, SIGTERM) != 0)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "PROCESS: Failed to terminate process");
|
TRACELOG(LOG_WARNING, "PROCESS: Failed to terminate process");
|
||||||
|
|
||||||
// Kill the process anyway
|
// Kill the process anyway
|
||||||
kill(process->pid, SIGKILL);
|
kill(process.pid, SIGKILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait process termination
|
// Wait process termination
|
||||||
waitpid(process->pid, NULL, 0);
|
waitpid(process.pid, NULL, 0);
|
||||||
|
|
||||||
// Align as CheckProcess() would do for a killed process
|
|
||||||
process->exitCode = -1;
|
|
||||||
process->pid = 0;
|
|
||||||
#else
|
#else
|
||||||
TRACELOG(LOG_WARNING, "PROCESS: Process management not supported on this platform");
|
TRACELOG(LOG_WARNING, "PROCESS: Process management not supported on this platform");
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user