github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/syscall/env_windows.go (about) 1 // Copyright 2010 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 // Windows environment variables. 6 7 package syscall 8 9 import ( 10 "unsafe" 11 ) 12 13 func Getenv(key string) (value string, found bool) { 14 keyp, err := UTF16PtrFromString(key) 15 if err != nil { 16 return "", false 17 } 18 n := uint32(100) 19 for { 20 b := make([]uint16, n) 21 n, err = GetEnvironmentVariable(keyp, &b[0], uint32(len(b))) 22 if n == 0 && err == ERROR_ENVVAR_NOT_FOUND { 23 return "", false 24 } 25 if n <= uint32(len(b)) { 26 return UTF16ToString(b[:n]), true 27 } 28 } 29 } 30 31 func Setenv(key, value string) error { 32 v, err := UTF16PtrFromString(value) 33 if err != nil { 34 return err 35 } 36 keyp, err := UTF16PtrFromString(key) 37 if err != nil { 38 return err 39 } 40 e := SetEnvironmentVariable(keyp, v) 41 if e != nil { 42 return e 43 } 44 runtimeSetenv(key, value) 45 return nil 46 } 47 48 func Unsetenv(key string) error { 49 keyp, err := UTF16PtrFromString(key) 50 if err != nil { 51 return err 52 } 53 e := SetEnvironmentVariable(keyp, nil) 54 if e != nil { 55 return e 56 } 57 runtimeUnsetenv(key) 58 return nil 59 } 60 61 func Clearenv() { 62 for _, s := range Environ() { 63 // Environment variables can begin with = 64 // so start looking for the separator = at j=1. 65 // https://blogs.msdn.com/b/oldnewthing/archive/2010/05/06/10008132.aspx 66 for j := 1; j < len(s); j++ { 67 if s[j] == '=' { 68 Unsetenv(s[0:j]) 69 break 70 } 71 } 72 } 73 } 74 75 func Environ() []string { 76 envp, e := GetEnvironmentStrings() 77 if e != nil { 78 return nil 79 } 80 defer FreeEnvironmentStrings(envp) 81 82 r := make([]string, 0, 50) // Empty with room to grow. 83 const size = unsafe.Sizeof(*envp) 84 for *envp != 0 { // environment block ends with empty string 85 // find NUL terminator 86 end := unsafe.Pointer(envp) 87 for *(*uint16)(end) != 0 { 88 end = unsafe.Add(end, size) 89 } 90 91 entry := unsafe.Slice(envp, (uintptr(end)-uintptr(unsafe.Pointer(envp)))/size) 92 r = append(r, UTF16ToString(entry)) 93 envp = (*uint16)(unsafe.Add(end, size)) 94 } 95 return r 96 }