From 565f5c8c5e5f8cf2f8a92cf9375f2f1c0e3ea034 Mon Sep 17 00:00:00 2001 From: Michael Schurter Date: Wed, 16 Aug 2017 14:54:50 -0700 Subject: [PATCH 1/2] Alter subprocess's environment instead of the hosts Fixes #415 --- internal/common/common_linux.go | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/internal/common/common_linux.go b/internal/common/common_linux.go index c0aa9c7..5347b60 100644 --- a/internal/common/common_linux.go +++ b/internal/common/common_linux.go @@ -9,15 +9,24 @@ import ( ) func DoSysctrl(mib string) ([]string, error) { - err := os.Setenv("LC_ALL", "C") - if err != nil { - return []string{}, err + hostEnv := os.Environ() + foundLC := false + for i, line := range hostEnv { + if strings.HasPrefix(line, "LC_ALL") { + hostEnv[i] = "LC_ALL=C" + foundLC = true + } + } + if !foundLC { + hostEnv = append(hostEnv, "LC_ALL=C") } sysctl, err := exec.LookPath("/sbin/sysctl") if err != nil { return []string{}, err } - out, err := exec.Command(sysctl, "-n", mib).Output() + cmd := exec.Command(sysctl, "-n", mib) + cmd.Env = hostEnv + out, err := cmd.Output() if err != nil { return []string{}, err } From 042305ee4a0dbd98e1fc106283bbe47e397e9d7e Mon Sep 17 00:00:00 2001 From: Michael Schurter Date: Wed, 16 Aug 2017 15:32:21 -0700 Subject: [PATCH 2/2] Remove SetEnv on all platforms --- internal/common/common.go | 16 ++++++++++++++++ internal/common/common_darwin.go | 9 +++------ internal/common/common_freebsd.go | 8 +++----- internal/common/common_linux.go | 13 +------------ internal/common/common_openbsd.go | 8 +++----- internal/common/common_test.go | 32 ++++++++++++++++++++++++++++++++ 6 files changed, 58 insertions(+), 28 deletions(-) diff --git a/internal/common/common.go b/internal/common/common.go index df71688..1ef9e27 100644 --- a/internal/common/common.go +++ b/internal/common/common.go @@ -358,3 +358,19 @@ func Pipeline(cmds ...*exec.Cmd) ([]byte, []byte, error) { // Return the pipeline output and the collected standard error return output.Bytes(), stderr.Bytes(), nil } + +// getSysctrlEnv sets LC_ALL=C in a list of env vars for use when running +// sysctl commands (see DoSysctrl). +func getSysctrlEnv(env []string) []string { + foundLC := false + for i, line := range env { + if strings.HasPrefix(line, "LC_ALL") { + env[i] = "LC_ALL=C" + foundLC = true + } + } + if !foundLC { + env = append(env, "LC_ALL=C") + } + return env +} diff --git a/internal/common/common_darwin.go b/internal/common/common_darwin.go index b236da1..2b6d4c1 100644 --- a/internal/common/common_darwin.go +++ b/internal/common/common_darwin.go @@ -12,16 +12,13 @@ import ( ) func DoSysctrl(mib string) ([]string, error) { - err := os.Setenv("LC_ALL", "C") - if err != nil { - return []string{}, err - } - sysctl, err := exec.LookPath("/usr/sbin/sysctl") if err != nil { return []string{}, err } - out, err := exec.Command(sysctl, "-n", mib).Output() + cmd := exec.Command(sysctl, "-n", mib) + cmd.Env = getSysctrlEnv(os.Environ()) + out, err := cmd.Output() if err != nil { return []string{}, err } diff --git a/internal/common/common_freebsd.go b/internal/common/common_freebsd.go index 668bdc4..107e2c9 100644 --- a/internal/common/common_freebsd.go +++ b/internal/common/common_freebsd.go @@ -12,15 +12,13 @@ import ( ) func DoSysctrl(mib string) ([]string, error) { - err := os.Setenv("LC_ALL", "C") - if err != nil { - return []string{}, err - } sysctl, err := exec.LookPath("/sbin/sysctl") if err != nil { return []string{}, err } - out, err := exec.Command(sysctl, "-n", mib).Output() + cmd := exec.Command(sysctl, "-n", mib) + cmd.Env = getSysctrlEnv(os.Environ()) + out, err := cmd.Output() if err != nil { return []string{}, err } diff --git a/internal/common/common_linux.go b/internal/common/common_linux.go index 5347b60..4e829e0 100644 --- a/internal/common/common_linux.go +++ b/internal/common/common_linux.go @@ -9,23 +9,12 @@ import ( ) func DoSysctrl(mib string) ([]string, error) { - hostEnv := os.Environ() - foundLC := false - for i, line := range hostEnv { - if strings.HasPrefix(line, "LC_ALL") { - hostEnv[i] = "LC_ALL=C" - foundLC = true - } - } - if !foundLC { - hostEnv = append(hostEnv, "LC_ALL=C") - } sysctl, err := exec.LookPath("/sbin/sysctl") if err != nil { return []string{}, err } cmd := exec.Command(sysctl, "-n", mib) - cmd.Env = hostEnv + cmd.Env = getSysctrlEnv(os.Environ()) out, err := cmd.Output() if err != nil { return []string{}, err diff --git a/internal/common/common_openbsd.go b/internal/common/common_openbsd.go index 8625e1f..398f785 100644 --- a/internal/common/common_openbsd.go +++ b/internal/common/common_openbsd.go @@ -12,15 +12,13 @@ import ( ) func DoSysctrl(mib string) ([]string, error) { - err := os.Setenv("LC_ALL", "C") - if err != nil { - return []string{}, err - } sysctl, err := exec.LookPath("/sbin/sysctl") if err != nil { return []string{}, err } - out, err := exec.Command(sysctl, "-n", mib).Output() + cmd := exec.Command(sysctl, "-n", mib) + cmd.Env = getSysctrlEnv(os.Environ()) + out, err := cmd.Output() if err != nil { return []string{}, err } diff --git a/internal/common/common_test.go b/internal/common/common_test.go index b7bda8b..3b05d53 100644 --- a/internal/common/common_test.go +++ b/internal/common/common_test.go @@ -2,6 +2,8 @@ package common import ( "fmt" + "os" + "reflect" "strings" "testing" ) @@ -95,3 +97,33 @@ func TestHostEtc(t *testing.T) { t.Errorf("invalid HostEtc, %s", p) } } + +func TestGetSysctrlEnv(t *testing.T) { + // Append case + env := getSysctrlEnv([]string{"FOO=bar"}) + if !reflect.DeepEqual(env, []string{"FOO=bar", "LC_ALL=C"}) { + t.Errorf("unexpected append result from getSysctrlEnv: %q", env) + } + + // Replace case + env = getSysctrlEnv([]string{"FOO=bar", "LC_ALL=en_US.UTF-8"}) + if !reflect.DeepEqual(env, []string{"FOO=bar", "LC_ALL=C"}) { + t.Errorf("unexpected replace result from getSysctrlEnv: %q", env) + } + + // Test against real env + env = getSysctrlEnv(os.Environ()) + found := false + for _, v := range env { + if v == "LC_ALL=C" { + found = true + continue + } + if strings.HasPrefix(v, "LC_ALL") { + t.Fatalf("unexpected LC_ALL value: %q", v) + } + } + if !found { + t.Errorf("unexpected real result from getSysctrlEnv: %q", env) + } +}