mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-04-29 02:34:23 +00:00
Added SDL_PROP_PROCESS_CREATE_BACKGROUND_BOOLEAN
This commit is contained in:
@@ -54,12 +54,14 @@ SDL_Process *SDL_CreateProcessWithProperties(SDL_PropertiesID props)
|
||||
if (!process) {
|
||||
return NULL;
|
||||
}
|
||||
process->background = SDL_GetBooleanProperty(props, SDL_PROP_PROCESS_CREATE_BACKGROUND_BOOLEAN, false);
|
||||
|
||||
process->props = SDL_CreateProperties();
|
||||
if (!process->props) {
|
||||
SDL_DestroyProcess(process);
|
||||
return NULL;
|
||||
}
|
||||
SDL_SetBooleanProperty(process->props, SDL_PROP_PROCESS_BACKGROUND_BOOLEAN, process->background);
|
||||
|
||||
if (!SDL_SYS_CreateProcessWithProperties(process, props)) {
|
||||
SDL_DestroyProcess(process);
|
||||
@@ -180,6 +182,9 @@ SDL_bool SDL_WaitProcess(SDL_Process *process, SDL_bool block, int *exitcode)
|
||||
if (SDL_SYS_WaitProcess(process, block, &process->exitcode)) {
|
||||
process->alive = false;
|
||||
if (exitcode) {
|
||||
if (process->background) {
|
||||
process->exitcode = 0;
|
||||
}
|
||||
*exitcode = process->exitcode;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -25,6 +25,7 @@ typedef struct SDL_ProcessData SDL_ProcessData;
|
||||
struct SDL_Process
|
||||
{
|
||||
bool alive;
|
||||
bool background;
|
||||
int exitcode;
|
||||
SDL_PropertiesID props;
|
||||
SDL_ProcessData *internal;
|
||||
|
||||
@@ -137,6 +137,19 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID
|
||||
goto posix_spawn_fail_attr;
|
||||
}
|
||||
|
||||
// Background processes don't have access to the terminal
|
||||
if (process->background) {
|
||||
if (stdin_option == SDL_PROCESS_STDIO_INHERITED) {
|
||||
stdin_option = SDL_PROCESS_STDIO_NULL;
|
||||
}
|
||||
if (stdout_option == SDL_PROCESS_STDIO_INHERITED) {
|
||||
stdout_option = SDL_PROCESS_STDIO_NULL;
|
||||
}
|
||||
if (stderr_option == SDL_PROCESS_STDIO_INHERITED) {
|
||||
stderr_option = SDL_PROCESS_STDIO_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
switch (stdin_option) {
|
||||
case SDL_PROCESS_STDIO_REDIRECT:
|
||||
if (!GetStreamFD(props, SDL_PROP_PROCESS_CREATE_STDIN_POINTER, &fd)) {
|
||||
@@ -276,9 +289,38 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID
|
||||
}
|
||||
|
||||
// Spawn the new process
|
||||
if (posix_spawnp(&data->pid, args[0], &fa, &attr, args, env) != 0) {
|
||||
SDL_SetError("posix_spawn failed: %s", strerror(errno));
|
||||
goto posix_spawn_fail_all;
|
||||
if (process->background) {
|
||||
int status = -1;
|
||||
pid_t pid = vfork();
|
||||
switch (pid) {
|
||||
case -1:
|
||||
SDL_SetError("vfork() failed: %s", strerror(errno));
|
||||
goto posix_spawn_fail_all;
|
||||
|
||||
case 0:
|
||||
// Detach from the terminal and launch the process
|
||||
setsid();
|
||||
if (posix_spawnp(&data->pid, args[0], &fa, &attr, args, env) != 0) {
|
||||
_exit(errno);
|
||||
}
|
||||
_exit(0);
|
||||
|
||||
default:
|
||||
if (waitpid(pid, &status, 0) < 0) {
|
||||
SDL_SetError("waitpid() failed: %s", strerror(errno));
|
||||
goto posix_spawn_fail_all;
|
||||
}
|
||||
if (status != 0) {
|
||||
SDL_SetError("posix_spawn() failed: %s", strerror(status));
|
||||
goto posix_spawn_fail_all;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (posix_spawnp(&data->pid, args[0], &fa, &attr, args, env) != 0) {
|
||||
SDL_SetError("posix_spawn() failed: %s", strerror(errno));
|
||||
goto posix_spawn_fail_all;
|
||||
}
|
||||
}
|
||||
SDL_SetNumberProperty(process->props, SDL_PROP_PROCESS_PID_NUMBER, data->pid);
|
||||
|
||||
@@ -353,26 +395,43 @@ bool SDL_SYS_KillProcess(SDL_Process *process, SDL_bool force)
|
||||
bool SDL_SYS_WaitProcess(SDL_Process *process, SDL_bool block, int *exitcode)
|
||||
{
|
||||
int wstatus = 0;
|
||||
int ret = waitpid(process->internal->pid, &wstatus, block ? 0 : WNOHANG);
|
||||
int ret;
|
||||
pid_t pid = process->internal->pid;
|
||||
|
||||
if (ret < 0) {
|
||||
return SDL_SetError("Could not waitpid(): %s", strerror(errno));
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
SDL_ClearError();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (WIFEXITED(wstatus)) {
|
||||
*exitcode = WEXITSTATUS(wstatus);
|
||||
} else if (WIFSIGNALED(wstatus)) {
|
||||
*exitcode = -WTERMSIG(wstatus);
|
||||
if (process->background) {
|
||||
// We can't wait on the status, so we'll poll to see if it's alive
|
||||
if (block) {
|
||||
while (kill(pid, 0) == 0) {
|
||||
SDL_Delay(10);
|
||||
}
|
||||
} else {
|
||||
if (kill(pid, 0) == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
*exitcode = 0;
|
||||
return true;
|
||||
} else {
|
||||
*exitcode = -255;
|
||||
}
|
||||
ret = waitpid(pid, &wstatus, block ? 0 : WNOHANG);
|
||||
if (ret < 0) {
|
||||
return SDL_SetError("Could not waitpid(): %s", strerror(errno));
|
||||
}
|
||||
|
||||
return true;
|
||||
if (ret == 0) {
|
||||
SDL_ClearError();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (WIFEXITED(wstatus)) {
|
||||
*exitcode = WEXITSTATUS(wstatus);
|
||||
} else if (WIFSIGNALED(wstatus)) {
|
||||
*exitcode = -WTERMSIG(wstatus);
|
||||
} else {
|
||||
*exitcode = -255;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_SYS_DestroyProcess(SDL_Process *process)
|
||||
|
||||
@@ -232,6 +232,20 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID
|
||||
security_attributes.bInheritHandle = TRUE;
|
||||
security_attributes.lpSecurityDescriptor = NULL;
|
||||
|
||||
// Background processes don't have access to the terminal
|
||||
// This isn't necessary on Windows, but we keep the same behavior as the POSIX implementation.
|
||||
if (process->background) {
|
||||
if (stdin_option == SDL_PROCESS_STDIO_INHERITED) {
|
||||
stdin_option = SDL_PROCESS_STDIO_NULL;
|
||||
}
|
||||
if (stdout_option == SDL_PROCESS_STDIO_INHERITED) {
|
||||
stdout_option = SDL_PROCESS_STDIO_NULL;
|
||||
}
|
||||
if (stderr_option == SDL_PROCESS_STDIO_INHERITED) {
|
||||
stderr_option = SDL_PROCESS_STDIO_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
switch (stdin_option) {
|
||||
case SDL_PROCESS_STDIO_REDIRECT:
|
||||
if (!SetupRedirect(props, SDL_PROP_PROCESS_CREATE_STDIN_POINTER, &startup_info.hStdInput)) {
|
||||
|
||||
Reference in New Issue
Block a user