mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-05-27 10:57:22 +08:00
Added SDL_PROP_PROCESS_CREATE_WORKING_DIRECTORY_STRING
Fixes https://github.com/libsdl-org/SDL/issues/12654
This commit is contained in:
@@ -1104,6 +1104,8 @@ if(SDL_LIBC)
|
|||||||
check_symbol_exists(poll "poll.h" HAVE_POLL)
|
check_symbol_exists(poll "poll.h" HAVE_POLL)
|
||||||
check_symbol_exists(memfd_create "sys/mman.h" HAVE_MEMFD_CREATE)
|
check_symbol_exists(memfd_create "sys/mman.h" HAVE_MEMFD_CREATE)
|
||||||
check_symbol_exists(posix_fallocate "fcntl.h" HAVE_POSIX_FALLOCATE)
|
check_symbol_exists(posix_fallocate "fcntl.h" HAVE_POSIX_FALLOCATE)
|
||||||
|
check_symbol_exists(posix_spawn_file_actions_addchdir "spawn.h" HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR)
|
||||||
|
check_symbol_exists(posix_spawn_file_actions_addchdir_np "spawn.h" HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP)
|
||||||
|
|
||||||
if(SDL_SYSTEM_ICONV)
|
if(SDL_SYSTEM_ICONV)
|
||||||
check_c_source_compiles("
|
check_c_source_compiles("
|
||||||
|
|||||||
@@ -166,6 +166,7 @@ typedef enum SDL_ProcessIO
|
|||||||
* - `SDL_PROP_PROCESS_CREATE_ENVIRONMENT_POINTER`: an SDL_Environment
|
* - `SDL_PROP_PROCESS_CREATE_ENVIRONMENT_POINTER`: an SDL_Environment
|
||||||
* pointer. If this property is set, it will be the entire environment for
|
* pointer. If this property is set, it will be the entire environment for
|
||||||
* the process, otherwise the current environment is used.
|
* the process, otherwise the current environment is used.
|
||||||
|
* - `SDL_PROP_PROCESS_CREATE_WORKING_DIRECTORY_STRING`: a UTF-8 encoded string representing the working directory for the process, defaults to the current working directory.
|
||||||
* - `SDL_PROP_PROCESS_CREATE_STDIN_NUMBER`: an SDL_ProcessIO value describing
|
* - `SDL_PROP_PROCESS_CREATE_STDIN_NUMBER`: an SDL_ProcessIO value describing
|
||||||
* where standard input for the process comes from, defaults to
|
* where standard input for the process comes from, defaults to
|
||||||
* `SDL_PROCESS_STDIO_NULL`.
|
* `SDL_PROCESS_STDIO_NULL`.
|
||||||
@@ -219,6 +220,7 @@ extern SDL_DECLSPEC SDL_Process * SDLCALL SDL_CreateProcessWithProperties(SDL_Pr
|
|||||||
|
|
||||||
#define SDL_PROP_PROCESS_CREATE_ARGS_POINTER "SDL.process.create.args"
|
#define SDL_PROP_PROCESS_CREATE_ARGS_POINTER "SDL.process.create.args"
|
||||||
#define SDL_PROP_PROCESS_CREATE_ENVIRONMENT_POINTER "SDL.process.create.environment"
|
#define SDL_PROP_PROCESS_CREATE_ENVIRONMENT_POINTER "SDL.process.create.environment"
|
||||||
|
#define SDL_PROP_PROCESS_CREATE_WORKING_DIRECTORY_STRING "SDL.process.create.working_directory"
|
||||||
#define SDL_PROP_PROCESS_CREATE_STDIN_NUMBER "SDL.process.create.stdin_option"
|
#define SDL_PROP_PROCESS_CREATE_STDIN_NUMBER "SDL.process.create.stdin_option"
|
||||||
#define SDL_PROP_PROCESS_CREATE_STDIN_POINTER "SDL.process.create.stdin_source"
|
#define SDL_PROP_PROCESS_CREATE_STDIN_POINTER "SDL.process.create.stdin_source"
|
||||||
#define SDL_PROP_PROCESS_CREATE_STDOUT_NUMBER "SDL.process.create.stdout_option"
|
#define SDL_PROP_PROCESS_CREATE_STDOUT_NUMBER "SDL.process.create.stdout_option"
|
||||||
|
|||||||
@@ -228,6 +228,8 @@
|
|||||||
#cmakedefine HAVE_SHOBJIDL_CORE_H 1
|
#cmakedefine HAVE_SHOBJIDL_CORE_H 1
|
||||||
|
|
||||||
#cmakedefine USE_POSIX_SPAWN 1
|
#cmakedefine USE_POSIX_SPAWN 1
|
||||||
|
#cmakedefine HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR 1
|
||||||
|
#cmakedefine HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP 1
|
||||||
|
|
||||||
/* SDL internal assertion support */
|
/* SDL internal assertion support */
|
||||||
#cmakedefine SDL_DEFAULT_ASSERT_LEVEL_CONFIGURED 1
|
#cmakedefine SDL_DEFAULT_ASSERT_LEVEL_CONFIGURED 1
|
||||||
|
|||||||
@@ -37,6 +37,12 @@
|
|||||||
#include "../../io/SDL_iostream_c.h"
|
#include "../../io/SDL_iostream_c.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP) && \
|
||||||
|
!defined(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR)
|
||||||
|
#define HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR
|
||||||
|
#define posix_spawn_file_actions_addchdir posix_spawn_file_actions_addchdir_np
|
||||||
|
#endif
|
||||||
|
|
||||||
#define READ_END 0
|
#define READ_END 0
|
||||||
#define WRITE_END 1
|
#define WRITE_END 1
|
||||||
|
|
||||||
@@ -156,6 +162,7 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID
|
|||||||
char * const *args = SDL_GetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ARGS_POINTER, NULL);
|
char * const *args = SDL_GetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ARGS_POINTER, NULL);
|
||||||
SDL_Environment *env = SDL_GetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ENVIRONMENT_POINTER, SDL_GetEnvironment());
|
SDL_Environment *env = SDL_GetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ENVIRONMENT_POINTER, SDL_GetEnvironment());
|
||||||
char **envp = NULL;
|
char **envp = NULL;
|
||||||
|
const char *working_directory = SDL_GetStringProperty(props, SDL_PROP_PROCESS_CREATE_WORKING_DIRECTORY_STRING, NULL);
|
||||||
SDL_ProcessIO stdin_option = (SDL_ProcessIO)SDL_GetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDIN_NUMBER, SDL_PROCESS_STDIO_NULL);
|
SDL_ProcessIO stdin_option = (SDL_ProcessIO)SDL_GetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDIN_NUMBER, SDL_PROCESS_STDIO_NULL);
|
||||||
SDL_ProcessIO stdout_option = (SDL_ProcessIO)SDL_GetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDOUT_NUMBER, SDL_PROCESS_STDIO_INHERITED);
|
SDL_ProcessIO stdout_option = (SDL_ProcessIO)SDL_GetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDOUT_NUMBER, SDL_PROCESS_STDIO_INHERITED);
|
||||||
SDL_ProcessIO stderr_option = (SDL_ProcessIO)SDL_GetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDERR_NUMBER, SDL_PROCESS_STDIO_INHERITED);
|
SDL_ProcessIO stderr_option = (SDL_ProcessIO)SDL_GetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDERR_NUMBER, SDL_PROCESS_STDIO_INHERITED);
|
||||||
@@ -192,6 +199,30 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID
|
|||||||
goto posix_spawn_fail_attr;
|
goto posix_spawn_fail_attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (working_directory) {
|
||||||
|
#ifdef HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR
|
||||||
|
#ifdef SDL_PLATFORM_APPLE
|
||||||
|
if (__builtin_available(macOS 10.15, *)) {
|
||||||
|
if (posix_spawn_file_actions_addchdir(&fa, working_directory) != 0) {
|
||||||
|
SDL_SetError("posix_spawn_file_actions_addchdir failed: %s", strerror(errno));
|
||||||
|
goto posix_spawn_fail_all;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SDL_SetError("Setting the working directory is only supported on macOS 10.15 and newer");
|
||||||
|
goto posix_spawn_fail_all;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (posix_spawn_file_actions_addchdir(&fa, working_directory) != 0) {
|
||||||
|
SDL_SetError("posix_spawn_file_actions_addchdir failed: %s", strerror(errno));
|
||||||
|
goto posix_spawn_fail_all;
|
||||||
|
}
|
||||||
|
#endif // SDL_PLATFORM_APPLE
|
||||||
|
#else
|
||||||
|
SDL_SetError("Setting the working directory is not supported");
|
||||||
|
goto posix_spawn_fail_all;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// Background processes don't have access to the terminal
|
// Background processes don't have access to the terminal
|
||||||
if (process->background) {
|
if (process->background) {
|
||||||
if (stdin_option == SDL_PROCESS_STDIO_INHERITED) {
|
if (stdin_option == SDL_PROCESS_STDIO_INHERITED) {
|
||||||
|
|||||||
@@ -239,6 +239,7 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID
|
|||||||
const char * const *args = SDL_GetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ARGS_POINTER, NULL);
|
const char * const *args = SDL_GetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ARGS_POINTER, NULL);
|
||||||
SDL_Environment *env = SDL_GetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ENVIRONMENT_POINTER, SDL_GetEnvironment());
|
SDL_Environment *env = SDL_GetPointerProperty(props, SDL_PROP_PROCESS_CREATE_ENVIRONMENT_POINTER, SDL_GetEnvironment());
|
||||||
char **envp = NULL;
|
char **envp = NULL;
|
||||||
|
const char *working_directory = SDL_GetStringProperty(props, SDL_PROP_PROCESS_CREATE_WORKING_DIRECTORY_STRING, NULL);
|
||||||
SDL_ProcessIO stdin_option = (SDL_ProcessIO)SDL_GetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDIN_NUMBER, SDL_PROCESS_STDIO_NULL);
|
SDL_ProcessIO stdin_option = (SDL_ProcessIO)SDL_GetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDIN_NUMBER, SDL_PROCESS_STDIO_NULL);
|
||||||
SDL_ProcessIO stdout_option = (SDL_ProcessIO)SDL_GetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDOUT_NUMBER, SDL_PROCESS_STDIO_INHERITED);
|
SDL_ProcessIO stdout_option = (SDL_ProcessIO)SDL_GetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDOUT_NUMBER, SDL_PROCESS_STDIO_INHERITED);
|
||||||
SDL_ProcessIO stderr_option = (SDL_ProcessIO)SDL_GetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDERR_NUMBER, SDL_PROCESS_STDIO_INHERITED);
|
SDL_ProcessIO stderr_option = (SDL_ProcessIO)SDL_GetNumberProperty(props, SDL_PROP_PROCESS_CREATE_STDERR_NUMBER, SDL_PROCESS_STDIO_INHERITED);
|
||||||
@@ -246,6 +247,7 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID
|
|||||||
!SDL_HasProperty(props, SDL_PROP_PROCESS_CREATE_STDERR_NUMBER);
|
!SDL_HasProperty(props, SDL_PROP_PROCESS_CREATE_STDERR_NUMBER);
|
||||||
LPWSTR createprocess_cmdline = NULL;
|
LPWSTR createprocess_cmdline = NULL;
|
||||||
LPWSTR createprocess_env = NULL;
|
LPWSTR createprocess_env = NULL;
|
||||||
|
LPWSTR createprocess_cwd = NULL;
|
||||||
STARTUPINFOW startup_info;
|
STARTUPINFOW startup_info;
|
||||||
DWORD creation_flags;
|
DWORD creation_flags;
|
||||||
SECURITY_ATTRIBUTES security_attributes;
|
SECURITY_ATTRIBUTES security_attributes;
|
||||||
@@ -292,6 +294,13 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (working_directory) {
|
||||||
|
createprocess_cwd = WIN_UTF8ToStringW(working_directory);
|
||||||
|
if (!createprocess_cwd) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Background processes don't have access to the terminal
|
// 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.
|
// This isn't necessary on Windows, but we keep the same behavior as the POSIX implementation.
|
||||||
if (process->background) {
|
if (process->background) {
|
||||||
@@ -427,7 +436,7 @@ bool SDL_SYS_CreateProcessWithProperties(SDL_Process *process, SDL_PropertiesID
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CreateProcessW(NULL, createprocess_cmdline, NULL, NULL, TRUE, creation_flags, createprocess_env, NULL, &startup_info, &data->process_information)) {
|
if (!CreateProcessW(NULL, createprocess_cmdline, NULL, NULL, TRUE, creation_flags, createprocess_env, createprocess_cwd, &startup_info, &data->process_information)) {
|
||||||
WIN_SetError("CreateProcess");
|
WIN_SetError("CreateProcess");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@@ -479,6 +488,7 @@ done:
|
|||||||
}
|
}
|
||||||
SDL_free(createprocess_cmdline);
|
SDL_free(createprocess_cmdline);
|
||||||
SDL_free(createprocess_env);
|
SDL_free(createprocess_env);
|
||||||
|
SDL_free(createprocess_cwd);
|
||||||
SDL_free(envp);
|
SDL_free(envp);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
|||||||
Reference in New Issue
Block a user