subprocess: don't initialize environment at startup
Currently, the subprocess package reads from the environment as it's created at startup when the init function is called. However, we'll soon want to modify the environment in this case before it gets processed, so let's change the code to use a mutex to initialize the environment once before using it and simply call that before using the environment we've set up. We'll want to reset the environment as well in a future commit, so let's be sure to add a function for that. We reuse the same internal function and just ignore the return value to make our code paths simpler.
This commit is contained in:
parent
19b2cd8e90
commit
59f1496289
@ -9,6 +9,7 @@ import (
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/rubyist/tracerx"
|
||||
)
|
||||
@ -128,6 +129,7 @@ func quotedArgs(args []string) string {
|
||||
|
||||
// An env for an exec.Command without GIT_TRACE and GIT_INTERNAL_SUPER_PREFIX
|
||||
var env []string
|
||||
var envMu sync.Mutex
|
||||
var traceEnv = "GIT_TRACE="
|
||||
|
||||
// Don't pass GIT_INTERNAL_SUPER_PREFIX back to Git. Git passes this environment
|
||||
@ -138,7 +140,20 @@ var traceEnv = "GIT_TRACE="
|
||||
// support --super-prefix and would immediately exit with an error as a result.
|
||||
var superPrefixEnv = "GIT_INTERNAL_SUPER_PREFIX="
|
||||
|
||||
func init() {
|
||||
func fetchEnvironment() []string {
|
||||
envMu.Lock()
|
||||
defer envMu.Unlock()
|
||||
|
||||
return fetchEnvironmentInternal()
|
||||
}
|
||||
|
||||
// fetchEnvironmentInternal should only be called from fetchEnvironment or
|
||||
// ResetEnvironment, who will hold the required lock.
|
||||
func fetchEnvironmentInternal() []string {
|
||||
if env != nil {
|
||||
return env
|
||||
}
|
||||
|
||||
realEnv := os.Environ()
|
||||
env = make([]string, 0, len(realEnv))
|
||||
|
||||
@ -148,4 +163,16 @@ func init() {
|
||||
}
|
||||
env = append(env, kv)
|
||||
}
|
||||
return env
|
||||
}
|
||||
|
||||
// ResetEnvironment resets the cached environment that's used in subprocess
|
||||
// calls.
|
||||
func ResetEnvironment() {
|
||||
envMu.Lock()
|
||||
defer envMu.Unlock()
|
||||
|
||||
env = nil
|
||||
// Reinitialize the environment settings.
|
||||
fetchEnvironmentInternal()
|
||||
}
|
||||
|
@ -9,6 +9,6 @@ import (
|
||||
// ExecCommand is a small platform specific wrapper around os/exec.Command
|
||||
func ExecCommand(name string, arg ...string) *Cmd {
|
||||
cmd := exec.Command(name, arg...)
|
||||
cmd.Env = env
|
||||
cmd.Env = fetchEnvironment()
|
||||
return newCmd(cmd)
|
||||
}
|
||||
|
@ -11,6 +11,6 @@ import (
|
||||
func ExecCommand(name string, arg ...string) *Cmd {
|
||||
cmd := exec.Command(name, arg...)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
|
||||
cmd.Env = env
|
||||
cmd.Env = fetchEnvironment()
|
||||
return newCmd(cmd)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user