refactor process manipulation API

This commit is contained in:
moe li 2026-05-25 11:50:56 +08:00
parent fc3cac5da3
commit c236b4eaaf
2 changed files with 74 additions and 51 deletions

View File

@ -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)

View File

@ -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)
{
info.state = PROCESS_STATE_RUNNING;
return info;
}
process->exitCode = (int)exitCode; info.state = PROCESS_STATE_FINISHED;
process->pid = 0; info.exitCode = (int)exitCode;
return false;
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