Commit 06c9ccdf authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

os/exec: always set SYSTEMROOT on Windows if not listed in Cmd.Env

Fixes #25210

Change-Id: If27b61776154dae9b9b67bf4e4f5faa785d98105
Reviewed-on: https://go-review.googlesource.com/c/go/+/174318Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent 8c1f7852
...@@ -71,6 +71,8 @@ type Cmd struct { ...@@ -71,6 +71,8 @@ type Cmd struct {
// environment. // environment.
// If Env contains duplicate environment keys, only the last // If Env contains duplicate environment keys, only the last
// value in the slice for each duplicate key is used. // 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 Env []string
// Dir specifies the working directory of the command. // Dir specifies the working directory of the command.
...@@ -412,7 +414,7 @@ func (c *Cmd) Start() error { ...@@ -412,7 +414,7 @@ func (c *Cmd) Start() error {
c.Process, err = os.StartProcess(c.Path, c.argv(), &os.ProcAttr{ c.Process, err = os.StartProcess(c.Path, c.argv(), &os.ProcAttr{
Dir: c.Dir, Dir: c.Dir,
Files: c.childFiles, Files: c.childFiles,
Env: dedupEnv(c.envv()), Env: addCriticalEnv(dedupEnv(c.envv())),
Sys: c.SysProcAttr, Sys: c.SysProcAttr,
}) })
if err != nil { if err != nil {
...@@ -756,3 +758,24 @@ func dedupEnvCase(caseInsensitive bool, env []string) []string { ...@@ -756,3 +758,24 @@ func dedupEnvCase(caseInsensitive bool, env []string) []string {
} }
return out 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"))
}
...@@ -1184,3 +1184,22 @@ func TestStringPathNotResolved(t *testing.T) { ...@@ -1184,3 +1184,22 @@ func TestStringPathNotResolved(t *testing.T) {
t.Errorf("String(%q, %q) = %q, want %q", "makemeasandwich", "-lettuce", got, want) 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")
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment