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
< path/filepath
< io/ioutil;
- os < internal/godebug;
-
path/filepath, internal/godebug < os/exec;
io/ioutil, os/exec, os/signal
--- /dev/null
+// 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
// 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).
// 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 {
{"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)
}
// 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"
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
}
}
// 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
}
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)
+ }
+}
{"adaptivestackstart", &debug.adaptivestackstart},
}
+var globalGODEBUG string
+
func parsedebugvars() {
// defaults
debug.cgocheck = 1
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 {
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 {
envs[i] = ""
delete(env, key)
}
- unsetenv_c(key)
+ runtimeUnsetenv(key)
return nil
}
envs = append(envs, kv)
}
env[key] = i
- setenv_c(key, value)
+ runtimeSetenv(key, value)
return nil
}
defer envLock.Unlock()
for k := range env {
- unsetenv_c(k)
+ runtimeUnsetenv(k)
}
env = make(map[string]int)
envs = []string{}
if e != nil {
return e
}
+ runtimeSetenv(key, value)
return nil
}
if err != nil {
return err
}
- return SetEnvironmentVariable(keyp, nil)
+ e := SetEnvironmentVariable(keyp, nil)
+ if e != nil {
+ return e
+ }
+ runtimeUnsetenv(key)
+ return nil
}
func Clearenv() {
func Getpagesize() int
func Exit(code int)
+
+// runtimeSetenv and runtimeUnsetenv are provided by the runtime.
+func runtimeSetenv(k, v string)
+func runtimeUnsetenv(k string)