-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
std::process::Command::env_clear
is unusable on Windows
#114737
Comments
Nominating this for t-libs-api discussion. Some notes:
|
@rustbot ping windows What should |
Hey Windows Group! This bug has been identified as a good "Windows candidate". cc @albertlarsan68 @arlosi @ChrisDenton @danielframpton @gdr-at-ms @kennykerr @luqmana @lzybkr @nico-abram @retep998 @rylev @sivadeilra @wesleywiser |
The Go prior art: https://pkg.go.dev/os/exec#Cmd type Cmd struct {
...
// Env specifies the environment of the process.
// Each entry is of the form "key=value".
// If Env is nil, the new process uses the current process's
// environment.
// If Env contains duplicate environment keys, only the last
// value in the slice for each duplicate key is used.
// As a special case on Windows, SYSTEMROOT is always added if
// missing and not explicitly set to the empty string.
Env []string
}
cmd := exec.Command(...)
cmd.Env = []string{} |
Something I don't see in the discussion here is reference to this line in the
Clears all explicitly set environment variables. It doesn't say anything about clearing all environment variables entirely. It even clarifies further:
Doesn't this mean that any variables inherited from the current process's parent process should be left alone? I haven't looked at the implementation at all so I don't know what it actually does on any platform other than Windows. |
I think the second part of the sentence is quite explicit, no:
|
Doh! Thanks for pointing that out 🤦 |
We discussed this in today's @rust-lang/libs-api meeting. @ChrisDenton made the point that specific DLLs (notably advapi) require this. Based on our discussion in the meeting, we felt there were two potentially reasonable alternatives:
|
Ah sorry, correction: it's not advapi32 itself that requires SystemRoot, but it can load additional DLLs that in turn do require it. This can vary depending on the exact functions that are used (go was using |
I think the most pertinent issue for Rust is that EDIT: The actual issue is that some system functions lazily load DLLs using paths stored in the registry. These paths are loaded from strings stored in the registry and expanded using ExpandEnvironmentStrings. which replaces e.g. |
One interesting alternative here (not sure if it's better, just another possibility) would be for Rust's startup code to check if SYSTEMROOT is set and set it if it isn't. That would make Rust work, but wouldn't help code launched by Rust. |
That assumes that Rust's startup code is run. I think we don't tend to assume that because there's many ways in which it might not be. |
@ChrisDenton Could also run it dynamically when invoking functions that need it. |
Ok, after considering this some more, here's wot I think. Usually I'd either want a (hypothetical) That said, the point I do strongly agree with is that functions in std should, as far as is reasonable1, "just work" cross-platform without needing special platform-specific knowledge. Not having If someone really really wants a clear environment, they can remove it with I'm not a fan of std dynamically setting the process environment before function calls. That seems brittle and will only work in very specific situations (e.g. when people go through std first). Footnotes
|
@ChrisDenton Sounds reasonable. It seems unlikely that clearing |
We wouldn't even necessarily have to preserve it. We could reset it to the value returned by |
Followed from the issue that was closed without an actual solution.
Problem
Windows requires some system envs in order to work and be able to run most of the programs and services. Without them they will fail like mentioned here
Possible solution
As described in comments to previous issue rust std could provide that system required envs in order to make
env_clear
more usable as it has done in libuv and goThe text was updated successfully, but these errors were encountered: