// 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
// Dir specifies the working directory of the command.
c.Process, err = os.StartProcess(c.Path, c.argv(), &os.ProcAttr{
Dir: c.Dir,
Files: c.childFiles,
- Env: dedupEnv(c.envv()),
+ Env: addCriticalEnv(dedupEnv(c.envv())),
Sys: c.SysProcAttr,
})
if err != nil {
}
return out
}
+
+// addCriticalEnv adds any critical environment variables that are required
+// (or at least almost always required) on the operating system.
+// Currently this is only used for Windows.
+func addCriticalEnv(env []string) []string {
+ if runtime.GOOS != "windows" {
+ return env
+ }
+ for _, kv := range env {
+ eq := strings.Index(kv, "=")
+ if eq < 0 {
+ continue
+ }
+ k := kv[:eq]
+ if strings.EqualFold(k, "SYSTEMROOT") {
+ // We already have it.
+ return env
+ }
+ }
+ return append(env, "SYSTEMROOT="+os.Getenv("SYSTEMROOT"))
+}
t.Errorf("String(%q, %q) = %q, want %q", "makemeasandwich", "-lettuce", got, want)
}
}
+
+// start a child process without the user code explicitly starting
+// with a copy of the parent's. (The Windows SYSTEMROOT issue: Issue
+// 25210)
+func TestChildCriticalEnv(t *testing.T) {
+ testenv.MustHaveExec(t)
+ if runtime.GOOS != "windows" {
+ t.Skip("only testing on Windows")
+ }
+ cmd := helperCommand(t, "echoenv", "SYSTEMROOT")
+ cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Fatal(err)
+ }
+ if strings.TrimSpace(string(out)) == "" {
+ t.Error("no SYSTEMROOT found")
+ }
+}