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
5// +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris windows
6
7package runtime
8
9import "unsafe"
10
11func gogetenv(key string) string {
12	env := environ()
13	if env == nil {
14		throw("getenv before env init")
15	}
16	for _, s := range env {
17		if len(s) > len(key) && s[len(key)] == '=' && envKeyEqual(s[:len(key)], key) {
18			return s[len(key)+1:]
19		}
20	}
21	return ""
22}
23
24// envKeyEqual reports whether a == b, with ASCII-only case insensitivity
25// on Windows. The two strings must have the same length.
26func envKeyEqual(a, b string) bool {
27	if GOOS == "windows" { // case insensitive
28		for i := 0; i < len(a); i++ {
29			ca, cb := a[i], b[i]
30			if ca == cb || lowerASCII(ca) == lowerASCII(cb) {
31				continue
32			}
33			return false
34		}
35		return true
36	}
37	return a == b
38}
39
40func lowerASCII(c byte) byte {
41	if 'A' <= c && c <= 'Z' {
42		return c + ('a' - 'A')
43	}
44	return c
45}
46
47var _cgo_setenv unsafe.Pointer   // pointer to C function
48var _cgo_unsetenv unsafe.Pointer // pointer to C function
49
50// Update the C environment if cgo is loaded.
51// Called from syscall.Setenv.
52//go:linkname syscall_setenv_c syscall.setenv_c
53func syscall_setenv_c(k string, v string) {
54	if _cgo_setenv == nil {
55		return
56	}
57	arg := [2]unsafe.Pointer{cstring(k), cstring(v)}
58	asmcgocall(_cgo_setenv, unsafe.Pointer(&arg))
59}
60
61// Update the C environment if cgo is loaded.
62// Called from syscall.unsetenv.
63//go:linkname syscall_unsetenv_c syscall.unsetenv_c
64func syscall_unsetenv_c(k string) {
65	if _cgo_unsetenv == nil {
66		return
67	}
68	arg := [1]unsafe.Pointer{cstring(k)}
69	asmcgocall(_cgo_unsetenv, unsafe.Pointer(&arg))
70}
71
72func cstring(s string) unsafe.Pointer {
73	p := make([]byte, len(s)+1)
74	copy(p, s)
75	return unsafe.Pointer(&p[0])
76}
77