]> Cypherpunks.ru repositories - gostls13.git/commitdiff
internal/godebug: remove dependency on os
authorRuss Cox <rsc@golang.org>
Mon, 17 Oct 2022 19:34:50 +0000 (15:34 -0400)
committerGopher Robot <gobot@golang.org>
Tue, 18 Oct 2022 14:49:44 +0000 (14:49 +0000)
The immediate reason is that we want to use godebug from math/rand,
and math/rand importing godebug importing os causes an import cycle
in package testing.

More generally, the new approach to backward compatibility outlined
in discussion #55090 will require using this package from other similarly
sensitive places, perhaps even package os itself. Best to remove all
dependencies.

Preparation for #54880.

Change-Id: Ia01657a2d90e707a8121a336c9db3b7247c0198f
Reviewed-on: https://go-review.googlesource.com/c/go/+/439418
Auto-Submit: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/go/build/deps_test.go
src/internal/godebug/export_test.go [new file with mode: 0644]
src/internal/godebug/godebug.go
src/internal/godebug/godebug_test.go
src/runtime/env_posix.go
src/runtime/runtime.go
src/runtime/runtime1.go
src/syscall/env_unix.go
src/syscall/env_windows.go
src/syscall/syscall.go

index 2fd5a39f75e9deefae78fa1e76abbd54304bb1fc..eed5c462be20a1c875f949459f577f78bdd7b646 100644 (file)
@@ -52,9 +52,13 @@ var depsRules = `
        internal/goarch, unsafe
        < internal/abi;
 
+       unsafe
+       < internal/godebug;
+
        # RUNTIME is the core runtime group of packages, all of them very light-weight.
        internal/abi, internal/cpu, internal/goarch,
-       internal/coverage/rtcov, internal/goexperiment, internal/goos, unsafe
+       internal/coverage/rtcov, internal/goexperiment,
+       internal/goos, internal/godebug, unsafe
        < internal/bytealg
        < internal/itoa
        < internal/unsafeheader
@@ -154,8 +158,6 @@ var depsRules = `
        < path/filepath
        < io/ioutil;
 
-       os < internal/godebug;
-
        path/filepath, internal/godebug < os/exec;
 
        io/ioutil, os/exec, os/signal
diff --git a/src/internal/godebug/export_test.go b/src/internal/godebug/export_test.go
new file mode 100644 (file)
index 0000000..e84d9a9
--- /dev/null
@@ -0,0 +1,7 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package godebug
+
+var Xget = get
index ac434e5fd83649f987326c1d55257d5712553786..65a8c4e3051078e8ba52c315c6ab81bd71fbf31c 100644 (file)
@@ -5,11 +5,14 @@
 // Package godebug parses the GODEBUG environment variable.
 package godebug
 
-import "os"
+import _ "unsafe" // go:linkname
+
+//go:linkname getGODEBUG
+func getGODEBUG() string
 
 // Get returns the value for the provided GODEBUG key.
 func Get(key string) string {
-       return get(os.Getenv("GODEBUG"), key)
+       return get(getGODEBUG(), key)
 }
 
 // get returns the value part of key=value in s (a GODEBUG value).
index 41b9117b73bcaf8b686fdde5c7ede0ded7ea1fc3..d7a2a7a8d8a96b9120c1bfc1d3b69802e315bde6 100644 (file)
@@ -2,9 +2,12 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package godebug
+package godebug_test
 
-import "testing"
+import (
+       . "internal/godebug"
+       "testing"
+)
 
 func TestGet(t *testing.T) {
        tests := []struct {
@@ -26,7 +29,7 @@ func TestGet(t *testing.T) {
                {"foo=bar,baz", "loooooooong", ""},
        }
        for _, tt := range tests {
-               got := get(tt.godebug, tt.key)
+               got := Xget(tt.godebug, tt.key)
                if got != tt.want {
                        t.Errorf("get(%q, %q) = %q; want %q", tt.godebug, tt.key, got, tt.want)
                }
index 94a19d80d8e86e0d8f3d65da2315a023c3639096..0eb4f0d7a3b8b25c3201d66376ed7f5564ee5456 100644 (file)
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build unix || (js && wasm) || windows || plan9
-
 package runtime
 
 import "unsafe"
@@ -48,10 +46,7 @@ var _cgo_setenv unsafe.Pointer   // pointer to C function
 var _cgo_unsetenv unsafe.Pointer // pointer to C function
 
 // Update the C environment if cgo is loaded.
-// Called from syscall.Setenv.
-//
-//go:linkname syscall_setenv_c syscall.setenv_c
-func syscall_setenv_c(k string, v string) {
+func setenv_c(k string, v string) {
        if _cgo_setenv == nil {
                return
        }
@@ -60,10 +55,7 @@ func syscall_setenv_c(k string, v string) {
 }
 
 // Update the C environment if cgo is loaded.
-// Called from syscall.unsetenv.
-//
-//go:linkname syscall_unsetenv_c syscall.unsetenv_c
-func syscall_unsetenv_c(k string) {
+func unsetenv_c(k string) {
        if _cgo_unsetenv == nil {
                return
        }
index 50f68a327caadcc78fbf5dc385dce9e5b46866c9..25b714de4e0f3175d67ce034586942da25633a36 100644 (file)
@@ -65,3 +65,31 @@ func os_runtime_args() []string { return append([]string{}, argslice...) }
 func syscall_Exit(code int) {
        exit(int32(code))
 }
+
+var godebugenv atomic.Pointer[string] // set by parsedebugvars
+
+//go:linkname godebug_getGODEBUG internal/godebug.getGODEBUG
+func godebug_getGODEBUG() string {
+       if p := godebugenv.Load(); p != nil {
+               return *p
+       }
+       return ""
+}
+
+//go:linkname syscall_runtimeSetenv syscall.runtimeSetenv
+func syscall_runtimeSetenv(key, value string) {
+       setenv_c(key, value)
+       if key == "GODEBUG" {
+               p := new(string)
+               *p = value
+               godebugenv.Store(p)
+       }
+}
+
+//go:linkname syscall_runtimeUnsetenv syscall.runtimeUnsetenv
+func syscall_runtimeUnsetenv(key string) {
+       unsetenv_c(key)
+       if key == "GODEBUG" {
+               godebugenv.Store(nil)
+       }
+}
index b0a458d18719b50f66f640a3e2551a54fda09152..a29608329cb6b35e08eec6ea9d132072833487a3 100644 (file)
@@ -355,6 +355,8 @@ var dbgvars = []dbgVar{
        {"adaptivestackstart", &debug.adaptivestackstart},
 }
 
+var globalGODEBUG string
+
 func parsedebugvars() {
        // defaults
        debug.cgocheck = 1
@@ -372,7 +374,9 @@ func parsedebugvars() {
                debug.madvdontneed = 1
        }
 
-       for p := gogetenv("GODEBUG"); p != ""; {
+       globalGODEBUG = gogetenv("GODEBUG")
+       godebugenv.StoreNoWB(&globalGODEBUG)
+       for p := globalGODEBUG; p != ""; {
                field := ""
                i := bytealg.IndexByteString(p, ',')
                if i < 0 {
index 67e6c5fbe2f6e82aff27becb7486cea35571bf4e..6d917da20835205c24ad6062aed2cf0a8344d91d 100644 (file)
@@ -31,11 +31,6 @@ var (
 
 func runtime_envs() []string // in package runtime
 
-// setenv_c and unsetenv_c are provided by the runtime but are no-ops
-// if cgo isn't loaded.
-func setenv_c(k, v string)
-func unsetenv_c(k string)
-
 func copyenv() {
        env = make(map[string]int)
        for i, s := range envs {
@@ -67,7 +62,7 @@ func Unsetenv(key string) error {
                envs[i] = ""
                delete(env, key)
        }
-       unsetenv_c(key)
+       runtimeUnsetenv(key)
        return nil
 }
 
@@ -124,7 +119,7 @@ func Setenv(key, value string) error {
                envs = append(envs, kv)
        }
        env[key] = i
-       setenv_c(key, value)
+       runtimeSetenv(key, value)
        return nil
 }
 
@@ -135,7 +130,7 @@ func Clearenv() {
        defer envLock.Unlock()
 
        for k := range env {
-               unsetenv_c(k)
+               runtimeUnsetenv(k)
        }
        env = make(map[string]int)
        envs = []string{}
index 74b154ec1519e3c10b5e0fed46f8ca5698ccd261..cd085a9e44732caddb362c46d2a149378733c521 100644 (file)
@@ -42,6 +42,7 @@ func Setenv(key, value string) error {
        if e != nil {
                return e
        }
+       runtimeSetenv(key, value)
        return nil
 }
 
@@ -50,7 +51,12 @@ func Unsetenv(key string) error {
        if err != nil {
                return err
        }
-       return SetEnvironmentVariable(keyp, nil)
+       e := SetEnvironmentVariable(keyp, nil)
+       if e != nil {
+               return e
+       }
+       runtimeUnsetenv(key)
+       return nil
 }
 
 func Clearenv() {
index 62bfa449cff5f27586dc5e30c6d553aff2a408f7..446a299f57dd60a4d98616d137b4762da922ae22 100644 (file)
@@ -100,3 +100,7 @@ func (tv *Timeval) Nano() int64 {
 
 func Getpagesize() int
 func Exit(code int)
+
+// runtimeSetenv and runtimeUnsetenv are provided by the runtime.
+func runtimeSetenv(k, v string)
+func runtimeUnsetenv(k string)