From efccd0a461fa8d5e3442fae8d2467537a866e6a5 Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Sat, 18 Jul 2026 02:03:41 +0100 Subject: [PATCH] fix(spawn): clean up initialized macOS state only The POSIX spawn initializers return error numbers directly. On failure the stub discarded those values and entered cleanup with spawn attributes, file actions, and spawn_info still uninitialized. Record each initializer result and track which objects were initialized so cleanup only destroys valid state and reports the original error. Signed-off-by: Rudi Grinberg --- otherlibs/stdune/src/spawn_stubs.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/otherlibs/stdune/src/spawn_stubs.c b/otherlibs/stdune/src/spawn_stubs.c index cf58dc14e16..c6407f00e3e 100644 --- a/otherlibs/stdune/src/spawn_stubs.c +++ b/otherlibs/stdune/src/spawn_stubs.c @@ -613,21 +613,30 @@ CAMLprim value dune_spawn_unix(value v_env, char *e_function = NULL; posix_spawn_file_actions_t actions; - if (posix_spawn_file_actions_init(&actions)) { + int actions_initialized = 0; + posix_spawnattr_t attr; + int attr_initialized = 0; + struct spawn_info info; + int info_initialized = 0; + + e_error = posix_spawn_file_actions_init(&actions); + if (e_error) { e_function = "posix_spawn_file_actions_init"; goto cleanup; } + actions_initialized = 1; - posix_spawnattr_t attr; - if (posix_spawnattr_init(&attr)) { + e_error = posix_spawnattr_init(&attr); + if (e_error) { e_function = "posix_spawnattr_init"; goto cleanup; } + attr_initialized = 1; - struct spawn_info info; init_spawn_info(&info, v_env, v_cwd, v_prog, v_argv, v_stdin, v_stdout, v_stderr, v_setpgid, v_sigprocmask, v_pdeathsig); + info_initialized = 1; short attr_flags = POSIX_SPAWN_SETSIGMASK; if (info.set_pgid) attr_flags |= POSIX_SPAWN_SETPGROUP; @@ -708,9 +717,12 @@ CAMLprim value dune_spawn_unix(value v_env, if (tmp_fds[fd] > 2) close(tmp_fds[fd]); - free_spawn_info(&info); - posix_spawnattr_destroy(&attr); - posix_spawn_file_actions_destroy(&actions); + if (info_initialized) + free_spawn_info(&info); + if (attr_initialized) + posix_spawnattr_destroy(&attr); + if (actions_initialized) + posix_spawn_file_actions_destroy(&actions); if (e_function) { unix_error(e_error, e_function, e_arg);