From 020f600f4f34dd9cb803baea54342a6c566340e3 Mon Sep 17 00:00:00 2001 From: Go Kudo Date: Mon, 11 May 2026 18:37:36 +0900 Subject: [PATCH] fix(macOS): SEGV on proc_open macOS 26 SDK --- ext/standard/proc_open.c | 25 +++++++++++- .../proc_open_cwd_basic.phpt | 38 +++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 ext/standard/tests/general_functions/proc_open_cwd_basic.phpt diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c index 111111406799..959b20ef9ce2 100644 --- a/ext/standard/proc_open.c +++ b/ext/standard/proc_open.c @@ -45,10 +45,31 @@ #define USE_POSIX_SPAWN /* The non-_np variant is in macOS 26 (and _np deprecated) */ -#ifdef HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR +#if defined(__APPLE__) && defined(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR) && defined(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP) +static inline int php_posix_spawn_file_actions_addchdir(posix_spawn_file_actions_t *actions, const char *path) +{ +/* The standardized symbol is weak-linked when building with a newer SDK. */ +# if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wunguarded-availability-new" +# endif + if (posix_spawn_file_actions_addchdir != NULL) { + return posix_spawn_file_actions_addchdir(actions, path); + } +# if defined(__clang__) +# pragma clang diagnostic pop +# endif + + return posix_spawn_file_actions_addchdir_np(actions, path); +} +#define POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR php_posix_spawn_file_actions_addchdir +#define POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NAME "posix_spawn_file_actions_addchdir" +#elif defined(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR) #define POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR posix_spawn_file_actions_addchdir +#define POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NAME "posix_spawn_file_actions_addchdir" #else #define POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR posix_spawn_file_actions_addchdir_np +#define POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NAME "posix_spawn_file_actions_addchdir_np" #endif #endif @@ -1401,7 +1422,7 @@ PHP_FUNCTION(proc_open) if (cwd) { r = POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR(&factions, cwd); if (r != 0) { - php_error_docref(NULL, E_WARNING, ZEND_TOSTR(POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR) "() failed: %s", strerror(r)); + php_error_docref(NULL, E_WARNING, POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NAME "() failed: %s", strerror(r)); } } diff --git a/ext/standard/tests/general_functions/proc_open_cwd_basic.phpt b/ext/standard/tests/general_functions/proc_open_cwd_basic.phpt new file mode 100644 index 000000000000..586c4866b004 --- /dev/null +++ b/ext/standard/tests/general_functions/proc_open_cwd_basic.phpt @@ -0,0 +1,38 @@ +--TEST-- +proc_open() with cwd changes child working directory +--SKIPIF-- + +--FILE-- + ['pipe', 'w'], + 2 => ['pipe', 'w'], +]; +$proc = proc_open([$php, '-n', '-r', 'echo basename(getcwd()), "\n";'], $descriptors, $pipes, $cwd); + +var_dump(is_resource($proc)); +echo stream_get_contents($pipes[1]); +echo stream_get_contents($pipes[2]); +fclose($pipes[1]); +fclose($pipes[2]); +var_dump(proc_close($proc)); + +rmdir($cwd); +?> +--CLEAN-- + +--EXPECT-- +bool(true) +proc_open_cwd_basic +int(0)