1// Copyright 2012 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package runtime 6 7import "unsafe" 8 9func gogetenv(key string) string { 10 env := environ() 11 if env == nil { 12 throw("getenv before env init") 13 } 14 for _, s := range env { 15 if len(s) > len(key) && s[len(key)] == '=' && envKeyEqual(s[:len(key)], key) { 16 return s[len(key)+1:] 17 } 18 } 19 return "" 20} 21 22// envKeyEqual reports whether a == b, with ASCII-only case insensitivity 23// on Windows. The two strings must have the same length. 24func envKeyEqual(a, b string) bool { 25 if GOOS == "windows" { // case insensitive 26 for i := 0; i < len(a); i++ { 27 ca, cb := a[i], b[i] 28 if ca == cb || lowerASCII(ca) == lowerASCII(cb) { 29 continue 30 } 31 return false 32 } 33 return true 34 } 35 return a == b 36} 37 38func lowerASCII(c byte) byte { 39 if 'A' <= c && c <= 'Z' { 40 return c + ('a' - 'A') 41 } 42 return c 43} 44 45// _cgo_setenv should be an internal detail, 46// but widely used packages access it using linkname. 47// Notable members of the hall of shame include: 48// - github.com/ebitengine/purego 49// 50// Do not remove or change the type signature. 51// See go.dev/issue/67401. 52// 53//go:linkname _cgo_setenv 54var _cgo_setenv unsafe.Pointer // pointer to C function 55 56// _cgo_unsetenv should be an internal detail, 57// but widely used packages access it using linkname. 58// Notable members of the hall of shame include: 59// - github.com/ebitengine/purego 60// 61// Do not remove or change the type signature. 62// See go.dev/issue/67401. 63// 64//go:linkname _cgo_unsetenv 65var _cgo_unsetenv unsafe.Pointer // pointer to C function 66 67// Update the C environment if cgo is loaded. 68func setenv_c(k string, v string) { 69 if _cgo_setenv == nil { 70 return 71 } 72 arg := [2]unsafe.Pointer{cstring(k), cstring(v)} 73 asmcgocall(_cgo_setenv, unsafe.Pointer(&arg)) 74} 75 76// Update the C environment if cgo is loaded. 77func unsetenv_c(k string) { 78 if _cgo_unsetenv == nil { 79 return 80 } 81 arg := [1]unsafe.Pointer{cstring(k)} 82 asmcgocall(_cgo_unsetenv, unsafe.Pointer(&arg)) 83} 84 85func cstring(s string) unsafe.Pointer { 86 p := make([]byte, len(s)+1) 87 copy(p, s) 88 return unsafe.Pointer(&p[0]) 89} 90