syscall: take over env implementation
The environment is needed by package time, which
we want not to depend on os (so that os can use
time.Time), so push down into syscall.
Delete syscall.Sleep, now unnecessary.
The package os environment API is preserved;
it is only the implementation that is moving to syscall.
Delete os.Envs, which was undocumented,
uninitialized on Windows and Plan 9, and
not maintained by Setenv and Clearenv.
Code can call os.Environ instead.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5370091
diff --git a/src/pkg/syscall/env_windows.go b/src/pkg/syscall/env_windows.go
new file mode 100644
index 0000000..8c1c427
--- /dev/null
+++ b/src/pkg/syscall/env_windows.go
@@ -0,0 +1,78 @@
+// Copyright 2010 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.
+
+// Windows environment variables.
+
+package syscall
+
+import (
+ "errors"
+ "unicode/utf16"
+ "unsafe"
+)
+
+func Getenv(key string) (value string, found bool) {
+ b := make([]uint16, 100)
+ n, e := GetEnvironmentVariable(StringToUTF16Ptr(key), &b[0], uint32(len(b)))
+ if n == 0 && e == ERROR_ENVVAR_NOT_FOUND {
+ return "", false
+ }
+ if n > uint32(len(b)) {
+ b = make([]uint16, n)
+ n, e = GetEnvironmentVariable(StringToUTF16Ptr(key), &b[0], uint32(len(b)))
+ if n > uint32(len(b)) {
+ n = 0
+ }
+ }
+ if n == 0 {
+ return "", false
+ }
+ return string(utf16.Decode(b[0:n])), true
+}
+
+func Setenv(key, value string) error {
+ var v *uint16
+ if len(value) > 0 {
+ v = StringToUTF16Ptr(value)
+ }
+ e := SetEnvironmentVariable(StringToUTF16Ptr(key), v)
+ if e != nil {
+ return e
+ }
+ return nil
+}
+
+func Clearenv() {
+ for _, s := range Environ() {
+ // Environment variables can begin with =
+ // so start looking for the separator = at j=1.
+ // http://blogs.msdn.com/b/oldnewthing/archive/2010/05/06/10008132.aspx
+ for j := 1; j < len(s); j++ {
+ if s[j] == '=' {
+ Setenv(s[0:j], "")
+ break
+ }
+ }
+ }
+}
+
+func Environ() []string {
+ s, e := GetEnvironmentStrings()
+ if e != nil {
+ return nil
+ }
+ defer FreeEnvironmentStrings(s)
+ r := make([]string, 0, 50) // Empty with room to grow.
+ for from, i, p := 0, 0, (*[1 << 24]uint16)(unsafe.Pointer(s)); true; i++ {
+ if p[i] == 0 {
+ // empty string marks the end
+ if i <= from {
+ break
+ }
+ r = append(r, string(utf16.Decode(p[from:i])))
+ from = i + 1
+ }
+ }
+ return r
+}