[rcore] add process execution functions for posix systems
This commit is contained in:
parent
ccc0d7452a
commit
24b36efbdc
13
src/raylib.h
13
src/raylib.h
|
|
@ -961,6 +961,12 @@ typedef enum {
|
||||||
NPATCH_THREE_PATCH_HORIZONTAL // Npatch layout: 3x1 tiles
|
NPATCH_THREE_PATCH_HORIZONTAL // Npatch layout: 3x1 tiles
|
||||||
} NPatchLayout;
|
} NPatchLayout;
|
||||||
|
|
||||||
|
// Process info
|
||||||
|
typedef struct Process {
|
||||||
|
int pid; // Process unique identifier
|
||||||
|
int exitCode; // Process exit code
|
||||||
|
} Process;
|
||||||
|
|
||||||
// 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
|
||||||
|
|
@ -1241,6 +1247,13 @@ RLAPI Vector2 GetTouchPosition(int index); // Get touch posit
|
||||||
RLAPI int GetTouchPointId(int index); // Get touch point identifier for given index
|
RLAPI int GetTouchPointId(int index); // Get touch point identifier for given index
|
||||||
RLAPI int GetTouchPointCount(void); // Get number of touch points
|
RLAPI int GetTouchPointCount(void); // Get number of touch points
|
||||||
|
|
||||||
|
// Process execution functions
|
||||||
|
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 void PauseProcess(Process *process); // Pause process execution
|
||||||
|
RLAPI void ResumeProcess(Process *process); // Resume paused process execution
|
||||||
|
RLAPI void CloseProcess(Process *process); // Close process and free resources
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Gestures and Touch Handling Functions (Module: rgestures)
|
// Gestures and Touch Handling Functions (Module: rgestures)
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
153
src/rcore.c
153
src/rcore.c
|
|
@ -210,6 +210,12 @@
|
||||||
#define ACCESS(fn) access(fn, F_OK)
|
#define ACCESS(fn) access(fn, F_OK)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
|
||||||
|
#include <sys/wait.h> // Required for: waitpid() [Used in CheckProcess()]
|
||||||
|
#include <signal.h> // Required for: kill() [Used in PauseProcess(), ResumeProcess(), CloseProcess()]
|
||||||
|
#include <sys/types.h> // Required for: pid_t [Used as function local variable type and for Process PID type]
|
||||||
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Defines and Macros
|
// Defines and Macros
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -4211,6 +4217,153 @@ int GetTouchPointCount(void)
|
||||||
return CORE.Input.Touch.pointCount;
|
return CORE.Input.Touch.pointCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
// Module Functions Definition: Process Execution
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Initialize a new process, returns a Process struct
|
||||||
|
RLAPI Process InitProcess(const char *command, char *const args[])
|
||||||
|
{
|
||||||
|
// The last element of the args array must be NULL
|
||||||
|
|
||||||
|
Process process = { 0 };
|
||||||
|
|
||||||
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
|
||||||
|
pid_t pid = fork();
|
||||||
|
|
||||||
|
if (pid < 0)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_WARNING, "PROCESS: Failed to create process");
|
||||||
|
}
|
||||||
|
else if (pid == 0)
|
||||||
|
{
|
||||||
|
// Child process
|
||||||
|
execvp(command, args);
|
||||||
|
|
||||||
|
// If execvp returns, it must have failed
|
||||||
|
_exit(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
process.pid = pid;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
TRACELOG(LOG_WARNING, "PROCESS: Process management not supported on this platform");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return process;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a process is still running, updates Process struct
|
||||||
|
RLAPI bool CheckProcess(Process *process)
|
||||||
|
{
|
||||||
|
if ((process == NULL) || (process->pid <= 0))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
|
||||||
|
int status = 0;
|
||||||
|
pid_t result = waitpid(process->pid, &status, WNOHANG);
|
||||||
|
|
||||||
|
if (result == 0)
|
||||||
|
{
|
||||||
|
// Still running
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (result == process->pid)
|
||||||
|
{
|
||||||
|
// Not running
|
||||||
|
if (WIFEXITED(status))
|
||||||
|
{
|
||||||
|
process->exitCode = WEXITSTATUS(status);
|
||||||
|
}
|
||||||
|
else if (WIFSIGNALED(status))
|
||||||
|
{
|
||||||
|
// Terminated by signal
|
||||||
|
process->exitCode = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark as completed
|
||||||
|
process->pid = 0;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Error occurred
|
||||||
|
TRACELOG(LOG_WARNING, "PROCESS: Failed to check process status");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
TRACELOG(LOG_WARNING, "PROCESS: Process management not supported on this platform");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pause process execution
|
||||||
|
RLAPI void PauseProcess(Process *process)
|
||||||
|
{
|
||||||
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
|
||||||
|
if (kill(process->pid, SIGSTOP) != 0)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_WARNING, "PROCESS: Failed to pause process");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
TRACELOG(LOG_WARNING, "PROCESS: Process management not supported on this platform");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resume paused process execution
|
||||||
|
RLAPI void ResumeProcess(Process *process)
|
||||||
|
{
|
||||||
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
|
||||||
|
if (kill(process->pid, SIGCONT) != 0)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_WARNING, "PROCESS: Failed to resume process");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
TRACELOG(LOG_WARNING, "PROCESS: Process management not supported on this platform");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close process and free resources
|
||||||
|
RLAPI void CloseProcess(Process *process)
|
||||||
|
{
|
||||||
|
if ((process == NULL) || (process->pid <= 0))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
|
||||||
|
if (!CheckProcess(process))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In case that the process is paused
|
||||||
|
kill(process->pid, SIGCONT);
|
||||||
|
|
||||||
|
if (kill(process->pid, SIGTERM) != 0)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_WARNING, "PROCESS: Failed to terminate process");
|
||||||
|
|
||||||
|
// Kill the process anyway
|
||||||
|
kill(process->pid, SIGKILL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait process termination
|
||||||
|
waitpid(process->pid, NULL, 0);
|
||||||
|
|
||||||
|
// Align as CheckProcess() would do for a killed process
|
||||||
|
process->exitCode = -1;
|
||||||
|
process->pid = 0;
|
||||||
|
#else
|
||||||
|
TRACELOG(LOG_WARNING, "PROCESS: Process management not supported on this platform");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Internal Functions Definition
|
// Module Internal Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user