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/os/Makefile b/src/pkg/os/Makefile
index 8923a8b..9bb2c0c 100644
--- a/src/pkg/os/Makefile
+++ b/src/pkg/os/Makefile
@@ -20,7 +20,6 @@
GOFILES_freebsd=\
dir_unix.go\
error_posix.go\
- env_unix.go\
file_posix.go\
file_unix.go\
path_unix.go\
@@ -32,7 +31,6 @@
GOFILES_darwin=\
dir_unix.go\
error_posix.go\
- env_unix.go\
file_posix.go\
file_unix.go\
path_unix.go\
@@ -44,7 +42,6 @@
GOFILES_linux=\
dir_unix.go\
error_posix.go\
- env_unix.go\
file_posix.go\
file_unix.go\
path_unix.go\
@@ -56,7 +53,6 @@
GOFILES_openbsd=\
dir_unix.go\
error_posix.go\
- env_unix.go\
file_posix.go\
file_unix.go\
path_unix.go\
@@ -68,7 +64,6 @@
GOFILES_windows=\
dir_windows.go\
error_posix.go\
- env_windows.go\
file_posix.go\
file_windows.go\
path_windows.go\
@@ -80,7 +75,6 @@
GOFILES_plan9=\
dir_plan9.go\
error_plan9.go\
- env_plan9.go\
file_plan9.go\
path_plan9.go\
sys_plan9.go\
diff --git a/src/pkg/os/env.go b/src/pkg/os/env.go
index 4844fa3..7e3f525 100644
--- a/src/pkg/os/env.go
+++ b/src/pkg/os/env.go
@@ -6,7 +6,10 @@
package os
-func setenv_c(k, v string)
+import (
+ "errors"
+ "syscall"
+)
// Expand replaces ${var} or $var in the string based on the mapping function.
// Invocations of undefined variables are replaced with the empty string.
@@ -73,3 +76,47 @@
}
return s[:i], i
}
+
+// ENOENV is the error indicating that an environment variable does not exist.
+var ENOENV = errors.New("no such environment variable")
+
+// Getenverror retrieves the value of the environment variable named by the key.
+// It returns the value and an error, if any.
+func Getenverror(key string) (value string, err error) {
+ if len(key) == 0 {
+ return "", EINVAL
+ }
+ val, found := syscall.Getenv(key)
+ if !found {
+ return "", ENOENV
+ }
+ return val, nil
+}
+
+// Getenv retrieves the value of the environment variable named by the key.
+// It returns the value, which will be empty if the variable is not present.
+func Getenv(key string) string {
+ v, _ := Getenverror(key)
+ return v
+}
+
+// Setenv sets the value of the environment variable named by the key.
+// It returns an error, if any.
+func Setenv(key, value string) error {
+ err := syscall.Setenv(key, value)
+ if err != nil {
+ return NewSyscallError("setenv", err)
+ }
+ return nil
+}
+
+// Clearenv deletes all environment variables.
+func Clearenv() {
+ syscall.Clearenv()
+}
+
+// Environ returns an array of strings representing the environment,
+// in the form "key=value".
+func Environ() []string {
+ return syscall.Environ()
+}
diff --git a/src/pkg/os/env_plan9.go b/src/pkg/os/env_plan9.go
deleted file mode 100644
index 286a5fe..0000000
--- a/src/pkg/os/env_plan9.go
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2011 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.
-
-// Plan 9 environment variables.
-
-package os
-
-import (
- "errors"
- "syscall"
-)
-
-// ENOENV is the error indicating that an environment variable does not exist.
-var ENOENV = errors.New("no such environment variable")
-
-// Getenverror retrieves the value of the environment variable named by the key.
-// It returns the value and an error, if any.
-func Getenverror(key string) (value string, err error) {
- if len(key) == 0 {
- return "", EINVAL
- }
- f, e := Open("/env/" + key)
- if e != nil {
- return "", ENOENV
- }
- defer f.Close()
-
- l, _ := f.Seek(0, 2)
- f.Seek(0, 0)
- buf := make([]byte, l)
- n, e := f.Read(buf)
- if e != nil {
- return "", ENOENV
- }
-
- if n > 0 && buf[n-1] == 0 {
- buf = buf[:n-1]
- }
- return string(buf), nil
-}
-
-// Getenv retrieves the value of the environment variable named by the key.
-// It returns the value, which will be empty if the variable is not present.
-func Getenv(key string) string {
- v, _ := Getenverror(key)
- return v
-}
-
-// Setenv sets the value of the environment variable named by the key.
-// It returns an error, if any.
-func Setenv(key, value string) error {
- if len(key) == 0 {
- return EINVAL
- }
-
- f, e := Create("/env/" + key)
- if e != nil {
- return e
- }
- defer f.Close()
-
- _, e = f.Write([]byte(value))
- return nil
-}
-
-// Clearenv deletes all environment variables.
-func Clearenv() {
- syscall.RawSyscall(syscall.SYS_RFORK, syscall.RFCENVG, 0, 0)
-}
-
-// Environ returns an array of strings representing the environment,
-// in the form "key=value".
-func Environ() []string {
- env := make([]string, 0, 100)
-
- f, e := Open("/env")
- if e != nil {
- panic(e)
- }
- defer f.Close()
-
- names, e := f.Readdirnames(-1)
- if e != nil {
- panic(e)
- }
-
- for _, k := range names {
- if v, e := Getenverror(k); e == nil {
- env = append(env, k+"="+v)
- }
- }
- return env[0:len(env)]
-}
-
-// TempDir returns the default directory to use for temporary files.
-func TempDir() string {
- return "/tmp"
-}
diff --git a/src/pkg/os/env_unix.go b/src/pkg/os/env_unix.go
deleted file mode 100644
index 01fd9d44..0000000
--- a/src/pkg/os/env_unix.go
+++ /dev/null
@@ -1,112 +0,0 @@
-// 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.
-
-// +build darwin freebsd linux openbsd
-
-// Unix environment variables.
-
-package os
-
-import (
- "errors"
- "sync"
-)
-
-// ENOENV is the error indicating that an environment variable does not exist.
-var ENOENV = errors.New("no such environment variable")
-
-var env map[string]string
-var once sync.Once
-
-func copyenv() {
- env = make(map[string]string)
- for _, s := range Envs {
- for j := 0; j < len(s); j++ {
- if s[j] == '=' {
- env[s[0:j]] = s[j+1:]
- break
- }
- }
- }
-}
-
-var envLock sync.RWMutex
-
-// Getenverror retrieves the value of the environment variable named by the key.
-// It returns the value and an error, if any.
-func Getenverror(key string) (value string, err error) {
- once.Do(copyenv)
-
- if len(key) == 0 {
- return "", EINVAL
- }
-
- envLock.RLock()
- defer envLock.RUnlock()
-
- v, ok := env[key]
- if !ok {
- return "", ENOENV
- }
- return v, nil
-}
-
-// Getenv retrieves the value of the environment variable named by the key.
-// It returns the value, which will be empty if the variable is not present.
-func Getenv(key string) string {
- v, _ := Getenverror(key)
- return v
-}
-
-// Setenv sets the value of the environment variable named by the key.
-// It returns an error, if any.
-func Setenv(key, value string) error {
- once.Do(copyenv)
- if len(key) == 0 {
- return EINVAL
- }
-
- envLock.Lock()
- defer envLock.Unlock()
-
- env[key] = value
- setenv_c(key, value) // is a no-op if cgo isn't loaded
- return nil
-}
-
-// Clearenv deletes all environment variables.
-func Clearenv() {
- once.Do(copyenv) // prevent copyenv in Getenv/Setenv
-
- envLock.Lock()
- defer envLock.Unlock()
-
- env = make(map[string]string)
-
- // TODO(bradfitz): pass through to C
-}
-
-// Environ returns an array of strings representing the environment,
-// in the form "key=value".
-func Environ() []string {
- once.Do(copyenv)
- envLock.RLock()
- defer envLock.RUnlock()
- a := make([]string, len(env))
- i := 0
- for k, v := range env {
- a[i] = k + "=" + v
- i++
- }
- return a
-}
-
-// TempDir returns the default directory to use for temporary files.
-func TempDir() string {
- dir := Getenv("TMPDIR")
- if dir == "" {
- dir = "/tmp"
- }
- return dir
-}
diff --git a/src/pkg/os/env_windows.go b/src/pkg/os/env_windows.go
deleted file mode 100644
index 88d6697..0000000
--- a/src/pkg/os/env_windows.go
+++ /dev/null
@@ -1,128 +0,0 @@
-// 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 os
-
-import (
- "errors"
- "syscall"
- "unicode/utf16"
- "unsafe"
-)
-
-// ENOENV is the error indicating that an environment variable does not exist.
-var ENOENV = errors.New("no such environment variable")
-
-// Getenverror retrieves the value of the environment variable named by the key.
-// It returns the value and an error, if any.
-func Getenverror(key string) (value string, err error) {
- b := make([]uint16, 100)
- n, e := syscall.GetEnvironmentVariable(syscall.StringToUTF16Ptr(key), &b[0], uint32(len(b)))
- if n == 0 && e == syscall.ERROR_ENVVAR_NOT_FOUND {
- return "", ENOENV
- }
- if n > uint32(len(b)) {
- b = make([]uint16, n)
- n, e = syscall.GetEnvironmentVariable(syscall.StringToUTF16Ptr(key), &b[0], uint32(len(b)))
- if n > uint32(len(b)) {
- n = 0
- }
- }
- if n == 0 {
- return "", NewSyscallError("GetEnvironmentVariable", e)
- }
- return string(utf16.Decode(b[0:n])), nil
-}
-
-// Getenv retrieves the value of the environment variable named by the key.
-// It returns the value, which will be empty if the variable is not present.
-func Getenv(key string) string {
- v, _ := Getenverror(key)
- return v
-}
-
-// Setenv sets the value of the environment variable named by the key.
-// It returns an error, if any.
-func Setenv(key, value string) error {
- var v *uint16
- if len(value) > 0 {
- v = syscall.StringToUTF16Ptr(value)
- }
- e := syscall.SetEnvironmentVariable(syscall.StringToUTF16Ptr(key), v)
- if e != nil {
- return NewSyscallError("SetEnvironmentVariable", e)
- }
- return nil
-}
-
-// Clearenv deletes all environment variables.
-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
- }
- }
- }
-}
-
-// Environ returns an array of strings representing the environment,
-// in the form "key=value".
-func Environ() []string {
- s, e := syscall.GetEnvironmentStrings()
- if e != nil {
- return nil
- }
- defer syscall.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
-}
-
-// TempDir returns the default directory to use for temporary files.
-func TempDir() string {
- const pathSep = '\\'
- dirw := make([]uint16, syscall.MAX_PATH)
- n, _ := syscall.GetTempPath(uint32(len(dirw)), &dirw[0])
- if n > uint32(len(dirw)) {
- dirw = make([]uint16, n)
- n, _ = syscall.GetTempPath(uint32(len(dirw)), &dirw[0])
- if n > uint32(len(dirw)) {
- n = 0
- }
- }
- if n > 0 && dirw[n-1] == pathSep {
- n--
- }
- return string(utf16.Decode(dirw[0:n]))
-}
-
-func init() {
- var argc int32
- cmd := syscall.GetCommandLine()
- argv, e := syscall.CommandLineToArgv(cmd, &argc)
- if e != nil {
- return
- }
- defer syscall.LocalFree(syscall.Handle(uintptr(unsafe.Pointer(argv))))
- Args = make([]string, argc)
- for i, v := range (*argv)[:argc] {
- Args[i] = string(syscall.UTF16ToString((*v)[:]))
- }
-}
diff --git a/src/pkg/os/exec_windows.go b/src/pkg/os/exec_windows.go
index f24580d..46adb05 100644
--- a/src/pkg/os/exec_windows.go
+++ b/src/pkg/os/exec_windows.go
@@ -65,3 +65,17 @@
}
return newProcess(pid, int(h)), nil
}
+
+func init() {
+ var argc int32
+ cmd := GetCommandLine()
+ argv, e := CommandLineToArgv(cmd, &argc)
+ if e != nil {
+ return
+ }
+ defer LocalFree(Handle(uintptr(unsafe.Pointer(argv))))
+ Args = make([]string, argc)
+ for i, v := range (*argv)[:argc] {
+ Args[i] = string(UTF16ToString((*v)[:]))
+ }
+}
diff --git a/src/pkg/os/file_plan9.go b/src/pkg/os/file_plan9.go
index ecdd5d5..15d6681 100644
--- a/src/pkg/os/file_plan9.go
+++ b/src/pkg/os/file_plan9.go
@@ -329,3 +329,8 @@
func (f *File) Chown(uid, gid int) error {
return EPLAN9
}
+
+// TempDir returns the default directory to use for temporary files.
+func TempDir() string {
+ return "/tmp"
+}
diff --git a/src/pkg/os/file_unix.go b/src/pkg/os/file_unix.go
index 140c93d..d8fcb22 100644
--- a/src/pkg/os/file_unix.go
+++ b/src/pkg/os/file_unix.go
@@ -241,3 +241,12 @@
return NewFile(p[0], "|0"), NewFile(p[1], "|1"), nil
}
+
+// TempDir returns the default directory to use for temporary files.
+func TempDir() string {
+ dir := Getenv("TMPDIR")
+ if dir == "" {
+ dir = "/tmp"
+ }
+ return dir
+}
diff --git a/src/pkg/os/file_windows.go b/src/pkg/os/file_windows.go
index 7dae46b..fef868c 100644
--- a/src/pkg/os/file_windows.go
+++ b/src/pkg/os/file_windows.go
@@ -283,3 +283,21 @@
return NewFile(p[0], "|0"), NewFile(p[1], "|1"), nil
}
+
+// TempDir returns the default directory to use for temporary files.
+func TempDir() string {
+ const pathSep = '\\'
+ dirw := make([]uint16, MAX_PATH)
+ n, _ := syscall.GetTempPath(uint32(len(dirw)), &dirw[0])
+ if n > uint32(len(dirw)) {
+ dirw = make([]uint16, n)
+ n, _ = syscall.GetTempPath(uint32(len(dirw)), &dirw[0])
+ if n > uint32(len(dirw)) {
+ n = 0
+ }
+ }
+ if n > 0 && dirw[n-1] == pathSep {
+ n--
+ }
+ return string(utf16.Decode(dirw[0:n]))
+}
diff --git a/src/pkg/os/os_test.go b/src/pkg/os/os_test.go
index 16b41f7..1b6cb80 100644
--- a/src/pkg/os/os_test.go
+++ b/src/pkg/os/os_test.go
@@ -18,7 +18,7 @@
var dot = []string{
"dir_unix.go",
- "env_unix.go",
+ "env.go",
"error.go",
"file.go",
"os_test.go",
diff --git a/src/pkg/os/proc.go b/src/pkg/os/proc.go
index d21f849..0ef6e41 100644
--- a/src/pkg/os/proc.go
+++ b/src/pkg/os/proc.go
@@ -8,8 +8,8 @@
import "syscall"
-var Args []string // provided by runtime
-var Envs []string // provided by runtime
+// Args is the command-line arguments, starting with the program name.
+var Args []string
// Getuid returns the numeric user id of the caller.
func Getuid() int { return syscall.Getuid() }
diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c
index 0b925fd..8f4d1ff 100644
--- a/src/pkg/runtime/proc.c
+++ b/src/pkg/runtime/proc.c
@@ -1723,9 +1723,9 @@
void (*libcgo_setenv)(byte**);
// Update the C environment if cgo is loaded.
-// Called from os.Setenv.
+// Called from syscall.Setenv.
void
-os·setenv_c(String k, String v)
+syscall·setenv_c(String k, String v)
{
byte *arg[2];
diff --git a/src/pkg/runtime/runtime.c b/src/pkg/runtime/runtime.c
index a82e8b6..a609a26 100644
--- a/src/pkg/runtime/runtime.c
+++ b/src/pkg/runtime/runtime.c
@@ -172,7 +172,7 @@
static uint8** argv;
Slice os·Args;
-Slice os·Envs;
+Slice syscall·envs;
void
runtime·args(int32 c, uint8 **v)
@@ -214,9 +214,9 @@
s = runtime·malloc(n*sizeof s[0]);
for(i=0; i<n; i++)
s[i] = runtime·gostringnocopy(argv[argc+1+i]);
- os·Envs.array = (byte*)s;
- os·Envs.len = n;
- os·Envs.cap = n;
+ syscall·envs.array = (byte*)s;
+ syscall·envs.len = n;
+ syscall·envs.cap = n;
}
byte*
@@ -229,8 +229,8 @@
bs = (byte*)s;
len = runtime·findnull(bs);
- envv = (String*)os·Envs.array;
- envc = os·Envs.len;
+ envv = (String*)syscall·envs.array;
+ envc = syscall·envs.len;
for(i=0; i<envc; i++){
if(envv[i].len <= len)
continue;
diff --git a/src/pkg/syscall/Makefile b/src/pkg/syscall/Makefile
index 2c4579f..3b4bbed 100644
--- a/src/pkg/syscall/Makefile
+++ b/src/pkg/syscall/Makefile
@@ -18,6 +18,7 @@
GOFILES_freebsd=\
bpf_bsd.go\
+ env_unix.go\
exec_unix.go\
route_bsd.go\
route_freebsd.go\
@@ -27,6 +28,7 @@
GOFILES_darwin=\
bpf_bsd.go\
+ env_unix.go\
exec_unix.go\
route_bsd.go\
route_darwin.go\
@@ -35,6 +37,7 @@
syscall_unix.go\
GOFILES_linux=\
+ env_unix.go\
exec_unix.go\
lsf_linux.go\
netlink_linux.go\
@@ -44,6 +47,7 @@
GOFILES_openbsd=\
bpf_bsd.go\
+ env_unix.go\
exec_unix.go\
route_bsd.go\
route_openbsd.go\
@@ -52,12 +56,14 @@
syscall_unix.go\
GOFILES_windows=\
+ env_windows.go\
exec_windows.go\
dll_windows.go\
zerrors_windows.go\
ztypes_windows.go\
GOFILES_plan9=\
+ env_plan9.go\
exec_plan9.go\
OFILES=\
diff --git a/src/pkg/syscall/env_plan9.go b/src/pkg/syscall/env_plan9.go
new file mode 100644
index 0000000..7a6ea90
--- /dev/null
+++ b/src/pkg/syscall/env_plan9.go
@@ -0,0 +1,74 @@
+// Copyright 2011 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.
+
+// Plan 9 environment variables.
+
+package syscall
+
+import "errors"
+
+func Getenv(key string) (value string, found bool) {
+ if len(key) == 0 {
+ return "", EINVAL
+ }
+ f, e := Open("/env/" + key)
+ if e != nil {
+ return "", ENOENV
+ }
+ defer f.Close()
+
+ l, _ := f.Seek(0, 2)
+ f.Seek(0, 0)
+ buf := make([]byte, l)
+ n, e := f.Read(buf)
+ if e != nil {
+ return "", ENOENV
+ }
+
+ if n > 0 && buf[n-1] == 0 {
+ buf = buf[:n-1]
+ }
+ return string(buf), nil
+}
+
+func Setenv(key, value string) error {
+ if len(key) == 0 {
+ return EINVAL
+ }
+
+ f, e := Create("/env/" + key)
+ if e != nil {
+ return e
+ }
+ defer f.Close()
+
+ _, e = f.Write([]byte(value))
+ return nil
+}
+
+func Clearenv() {
+ RawSyscall(SYS_RFORK, RFCENVG, 0, 0)
+}
+
+func Environ() []string {
+ env := make([]string, 0, 100)
+
+ f, e := Open("/env")
+ if e != nil {
+ panic(e)
+ }
+ defer f.Close()
+
+ names, e := f.Readdirnames(-1)
+ if e != nil {
+ panic(e)
+ }
+
+ for _, k := range names {
+ if v, ok := Getenv(k); ok {
+ env = append(env, k+"="+v)
+ }
+ }
+ return env[0:len(env)]
+}
diff --git a/src/pkg/syscall/env_unix.go b/src/pkg/syscall/env_unix.go
new file mode 100644
index 0000000..94a64713
--- /dev/null
+++ b/src/pkg/syscall/env_unix.go
@@ -0,0 +1,85 @@
+// 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.
+
+// +build darwin freebsd linux openbsd
+
+// Unix environment variables.
+
+package syscall
+
+import "sync"
+
+var env map[string]string
+var envOnce sync.Once
+var envs []string // provided by runtime
+
+func setenv_c(k, v string)
+
+func copyenv() {
+ env = make(map[string]string)
+ for _, s := range envs {
+ for j := 0; j < len(s); j++ {
+ if s[j] == '=' {
+ env[s[0:j]] = s[j+1:]
+ break
+ }
+ }
+ }
+}
+
+var envLock sync.RWMutex
+
+func Getenv(key string) (value string, found bool) {
+ envOnce.Do(copyenv)
+ if len(key) == 0 {
+ return "", false
+ }
+
+ envLock.RLock()
+ defer envLock.RUnlock()
+
+ v, ok := env[key]
+ if !ok {
+ return "", false
+ }
+ return v, true
+}
+
+func Setenv(key, value string) error {
+ envOnce.Do(copyenv)
+ if len(key) == 0 {
+ return EINVAL
+ }
+
+ envLock.Lock()
+ defer envLock.Unlock()
+
+ env[key] = value
+ setenv_c(key, value) // is a no-op if cgo isn't loaded
+ return nil
+}
+
+func Clearenv() {
+ envOnce.Do(copyenv) // prevent copyenv in Getenv/Setenv
+
+ envLock.Lock()
+ defer envLock.Unlock()
+
+ env = make(map[string]string)
+
+ // TODO(bradfitz): pass through to C
+}
+
+func Environ() []string {
+ envOnce.Do(copyenv)
+ envLock.RLock()
+ defer envLock.RUnlock()
+ a := make([]string, len(env))
+ i := 0
+ for k, v := range env {
+ a[i] = k + "=" + v
+ i++
+ }
+ return a
+}
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
+}
diff --git a/src/pkg/syscall/syscall_bsd.go b/src/pkg/syscall/syscall_bsd.go
index 9d02d12..c8ffd09 100644
--- a/src/pkg/syscall/syscall_bsd.go
+++ b/src/pkg/syscall/syscall_bsd.go
@@ -137,11 +137,6 @@
return
}
-func Sleep(ns int64) (err error) {
- tv := NsecToTimeval(ns)
- return Select(0, nil, nil, nil, &tv)
-}
-
//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys bind(s int, addr uintptr, addrlen _Socklen) (err error)
//sys connect(s int, addr uintptr, addrlen _Socklen) (err error)
diff --git a/src/pkg/syscall/syscall_linux.go b/src/pkg/syscall/syscall_linux.go
index 52a7dc2..bae7f20 100644
--- a/src/pkg/syscall/syscall_linux.go
+++ b/src/pkg/syscall/syscall_linux.go
@@ -184,12 +184,6 @@
return
}
-func Sleep(nsec int64) (err error) {
- tv := NsecToTimeval(nsec)
- _, err = Select(0, nil, nil, nil, &tv)
- return err
-}
-
func Mkfifo(path string, mode uint32) (err error) {
return Mknod(path, mode|S_IFIFO, 0)
}
diff --git a/src/pkg/syscall/syscall_plan9.go b/src/pkg/syscall/syscall_plan9.go
index 0409a04..2005d81 100644
--- a/src/pkg/syscall/syscall_plan9.go
+++ b/src/pkg/syscall/syscall_plan9.go
@@ -163,11 +163,6 @@
return
}
-//sys sleep(millisecs int32) (err Error)
-func Sleep(nsec int64) (err Error) {
- return sleep(int32((nsec + 999) / 1e6)) // round up to microsecond
-}
-
// Underlying system call writes to newoffset via pointer.
// Implemented in assembly to avoid allocation.
func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string)
diff --git a/src/pkg/syscall/syscall_windows.go b/src/pkg/syscall/syscall_windows.go
index db8d3bc..2c0cc54 100644
--- a/src/pkg/syscall/syscall_windows.go
+++ b/src/pkg/syscall/syscall_windows.go
@@ -110,7 +110,6 @@
//sys GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW
//sys SetEndOfFile(handle Handle) (err error)
//sys GetSystemTimeAsFileTime(time *Filetime)
-//sys sleep(msec uint32) = Sleep
//sys GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff]
//sys CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error)
//sys GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error)
diff --git a/src/pkg/syscall/zsyscall_windows_386.go b/src/pkg/syscall/zsyscall_windows_386.go
index 5701024..7970d3e 100644
--- a/src/pkg/syscall/zsyscall_windows_386.go
+++ b/src/pkg/syscall/zsyscall_windows_386.go
@@ -41,7 +41,6 @@
procGetComputerNameW = modkernel32.NewProc("GetComputerNameW")
procSetEndOfFile = modkernel32.NewProc("SetEndOfFile")
procGetSystemTimeAsFileTime = modkernel32.NewProc("GetSystemTimeAsFileTime")
- procSleep = modkernel32.NewProc("Sleep")
procGetTimeZoneInformation = modkernel32.NewProc("GetTimeZoneInformation")
procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort")
procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
@@ -427,11 +426,6 @@
return
}
-func sleep(msec uint32) {
- Syscall(procSleep.Addr(), 1, uintptr(msec), 0, 0)
- return
-}
-
func GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) {
r0, _, e1 := Syscall(procGetTimeZoneInformation.Addr(), 1, uintptr(unsafe.Pointer(tzi)), 0, 0)
rc = uint32(r0)
diff --git a/src/pkg/syscall/zsyscall_windows_amd64.go b/src/pkg/syscall/zsyscall_windows_amd64.go
index 56d4399..49c5fb0 100644
--- a/src/pkg/syscall/zsyscall_windows_amd64.go
+++ b/src/pkg/syscall/zsyscall_windows_amd64.go
@@ -41,7 +41,6 @@
procGetComputerNameW = modkernel32.NewProc("GetComputerNameW")
procSetEndOfFile = modkernel32.NewProc("SetEndOfFile")
procGetSystemTimeAsFileTime = modkernel32.NewProc("GetSystemTimeAsFileTime")
- procSleep = modkernel32.NewProc("Sleep")
procGetTimeZoneInformation = modkernel32.NewProc("GetTimeZoneInformation")
procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort")
procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
@@ -427,11 +426,6 @@
return
}
-func sleep(msec uint32) {
- Syscall(procSleep.Addr(), 1, uintptr(msec), 0, 0)
- return
-}
-
func GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) {
r0, _, e1 := Syscall(procGetTimeZoneInformation.Addr(), 1, uintptr(unsafe.Pointer(tzi)), 0, 0)
rc = uint32(r0)