Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
    npro  
 Modern all-safe Rust Network Protocol library supporting h1, h2, h3, ws, wt sans-IO and with socket IO + tls
git clone https://npro.rs/repo/npro
 
root / assets / rocky9-ca.svg
Author[]Andy Green <andy@warmcat.com> 2026-09-11 04:19 UTC
Committer[]Andy Green <andy@warmcat.com> 2026-09-11 04:19 UTC
Tree60b148e9f355bc69c2bc7dd17d7e4ca44b067f66   Raw Patch
 
builder: windows: let spawned children inherit the builder's environment
builder: windows: let spawned children inherit the builder's environment

Since lws f92e831dd (C-328) the Windows spawn honours env_array as the
child's entire environment, the way execve does.  Before that it was
silently ignored and children inherited the builder's environment.

The builder hands every spawn its unix sanitizing set: a unix PATH,
LANG and TERM, and nothing else.  A Windows child given only that has
no SystemRoot and none of the Visual Studio variables the service was
started with, so after updating, every build died in cmake with
"Running 'nmake' '-?' failed with: no such file or directory" and
CMAKE_C_COMPILER not set.

On Windows pass no env_array, so the child inherits ours as it always
effectively did.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
diff --git a/src/builder/b-nspawn.c b/src/builder/b-nspawn.c index 9390658..e2d42a9 100644 --- a/src/builder/b-nspawn.c +++ b/src/builder/b-nspawn.c @@ -581,12 +581,14 @@ saib_spawn_script(struct sai_nspawn *ns) "/bin/ps", NULL }; +#if !defined(WIN32) const char *env[] = { "PATH=/usr/local/bin:/usr/bin:/bin", "LANG=en_US.UTF-8", "TERM=xterm-256color", NULL }; +#endif char one_step[4096]; char st[2048]; int fd, n; @@ -686,7 +688,18 @@ saib_spawn_script(struct sai_nspawn *ns) memset(&info, 0, sizeof(info)); info.vh = builder.vhost; +#if !defined(WIN32) info.env_array = (const char **)env; +#else + /* + * Since lws C-328 (f92e831dd) the Windows spawn honours env_array as + * the child's entire environment, as execve does; before it was + * ignored and the child inherited ours. The sanitizing set above is + * a unix PATH with no SystemRoot or Visual Studio variables, so a + * child given it cannot even find nmake or cl. Inherit instead. + */ + info.env_array = NULL; +#endif info.exec_array = cmd; info.protocol_name = "sai-stdxxx"; info.max_log_lines = 10000; @@ -866,12 +879,14 @@ saib_shell_spawn(struct sai_plat_server *spm, const char *task_uuid) struct lws_spawn_piped_info info; struct sai_shell *sh; const char *cmd[] = { "/bin/bash", "-i", NULL }; +#if !defined(WIN32) const char *env[] = { "PATH=/usr/local/bin:/usr/bin:/bin", "LANG=en_US.UTF-8", "TERM=xterm-256color", NULL }; +#endif sh = malloc(sizeof(*sh)); if (!sh) @@ -883,7 +898,18 @@ saib_shell_spawn(struct sai_plat_server *spm, const char *task_uuid) memset(&info, 0, sizeof(info)); info.vh = builder.vhost; +#if !defined(WIN32) info.env_array = (const char **)env; +#else + /* + * Since lws C-328 (f92e831dd) the Windows spawn honours env_array as + * the child's entire environment, as execve does; before it was + * ignored and the child inherited ours. The sanitizing set above is + * a unix PATH with no SystemRoot or Visual Studio variables, so a + * child given it cannot even find nmake or cl. Inherit instead. + */ + info.env_array = NULL; +#endif info.exec_array = cmd; info.protocol_name = "sai-saishell"; info.max_log_lines = 10000;
Page fetched 0s ago, creation time: 2ms (vhost etag hits: 0%, cache hits: 0%)