https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=1f836c5f7394ccde8b2f502d632ac8e07835586d
commit 1f836c5f7394ccde8b2f502d632ac8e07835586d Author: Takashi Yano <takashi.y...@nifty.ne.jp> Date: Sat Jul 19 23:49:26 2025 +0900 Cygwin: spawn: Make system() thread-safe POSIX states system() shall be thread-safe, however, it is not in current cygwin. This is because ch_spawn is a global and is shared between threads. With this patch, system() uses ch_spawn_local instead which is local variable. popen() has the same problem, so it has been fixed in the same way. Addresses: https://cygwin.com/pipermail/cygwin/2025-June/258324.html Fixes: 1fd5e000ace5 ("import winsup-2000-02-17 snapshot") Reported-by: Takashi Yano <takashi.y...@nifty.ne.jp> Reviewed-by: Corinna Vinschen <cori...@vinschen.de> Signed-off-by: Takashi Yano <takashi.y...@nifty.ne.jp> Diff: --- winsup/cygwin/spawn.cc | 3 ++- winsup/cygwin/syscalls.cc | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 7f2f5a8aa..680f0fefd 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -950,6 +950,7 @@ spawnve (int mode, const char *path, const char *const *argv, if (!envp) envp = empty_env; + child_info_spawn ch_spawn_local (_CH_NADA, false); switch (_P_MODE (mode)) { case _P_OVERLAY: @@ -963,7 +964,7 @@ spawnve (int mode, const char *path, const char *const *argv, case _P_WAIT: case _P_DETACH: case _P_SYSTEM: - ret = ch_spawn.worker (path, argv, envp, mode); + ret = ch_spawn_local.worker (path, argv, envp, mode); break; default: set_errno (EINVAL); diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index d6a2c2d3b..863f8f23c 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -4535,8 +4535,9 @@ popen (const char *command, const char *in_type) fcntl (stdchild, F_SETFD, stdchild_state | FD_CLOEXEC); /* Start a shell process to run the given command without forking. */ - pid_t pid = ch_spawn.worker ("/bin/sh", argv, environ, _P_NOWAIT, - __std[0], __std[1]); + child_info_spawn ch_spawn_local (_CH_NADA, false); + pid_t pid = ch_spawn_local.worker ("/bin/sh", argv, environ, _P_NOWAIT, + __std[0], __std[1]); /* Reinstate the close-on-exec state */ fcntl (stdchild, F_SETFD, stdchild_state);