diff --git a/src/pkg/os/Makefile b/src/pkg/os/Makefile index 8923a8b480237c8ccfae794b1da40c8a8952fa1c..9bb2c0cbf157451bfd791a4787ed2197491a595b 100644 --- a/src/pkg/os/Makefile +++ b/src/pkg/os/Makefile @@ -20,7 +20,6 @@ GOFILES=\ 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_freebsd=\ 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_darwin=\ 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_linux=\ 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_openbsd=\ 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_windows=\ 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 4844fa3e26d61280b500c1deaa567f781016730e..7e3f52502e54ef93afec26e75991de666e19c17c 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 @@ func getShellName(s string) (string, int) { } 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 286a5fe5a2cb840c4022540ec20ea22bcec5dff2..0000000000000000000000000000000000000000 --- 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 01fd9d449f36bd730a95fbc7afb1220ede4f2a9e..0000000000000000000000000000000000000000 --- 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 88d669731caa4587076e82e75c1fb3a347c56163..0000000000000000000000000000000000000000 --- 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 f24580d15c9df29cec9c1b64ff899e08b253f516..46adb050d8b272b62c7cde3c2509bb300074c5de 100644 --- a/src/pkg/os/exec_windows.go +++ b/src/pkg/os/exec_windows.go @@ -65,3 +65,17 @@ func FindProcess(pid int) (p *Process, err error) { } 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 ecdd5d51efa342da437afa206de87a6932257506..15d66813a207ceb10a9fccaba52acabf5c167b90 100644 --- a/src/pkg/os/file_plan9.go +++ b/src/pkg/os/file_plan9.go @@ -329,3 +329,8 @@ func Lchown(name string, uid, gid int) error { 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 140c93d8f24038357bb715fccd6b945d82891e71..d8fcb22ae1be955ef4af6abdd4e8f888faf85193 100644 --- a/src/pkg/os/file_unix.go +++ b/src/pkg/os/file_unix.go @@ -241,3 +241,12 @@ func Pipe() (r *File, w *File, err error) { 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 7dae46b212249273971541b6f044c6dd2e1a1935..fef868c68e62361ebae392cf5670019f7ff44dd3 100644 --- a/src/pkg/os/file_windows.go +++ b/src/pkg/os/file_windows.go @@ -283,3 +283,21 @@ func Pipe() (r *File, w *File, err error) { 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 16b41f7b6659c97912cd025e99477a053c4edbca..1b6cb8028c2532e3ecf0597b8db6ef9f76abaf75 100644 --- a/src/pkg/os/os_test.go +++ b/src/pkg/os/os_test.go @@ -18,7 +18,7 @@ import ( 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 d21f849f21085d12106f0278507f739be2faf6e2..0ef6e411c314e48e9d87f6dfc3290a447e52a798 100644 --- a/src/pkg/os/proc.go +++ b/src/pkg/os/proc.go @@ -8,8 +8,8 @@ package os 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 0b925fd52527683bd7be55a26799ff4d1e22ea75..8f4d1ffb4c6f94786094a2346072420dd1ebec4c 100644 --- a/src/pkg/runtime/proc.c +++ b/src/pkg/runtime/proc.c @@ -1723,9 +1723,9 @@ runtime·setcpuprofilerate(void (*fn)(uintptr*, int32), int32 hz) 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 a82e8b6b4908685939c103b4c889a3c93b6dbecc..a609a26f80f4ec4a0097780aeca40c08012bcb51 100644 --- a/src/pkg/runtime/runtime.c +++ b/src/pkg/runtime/runtime.c @@ -172,7 +172,7 @@ static int32 argc; static uint8** argv; Slice os·Args; -Slice os·Envs; +Slice syscall·envs; void runtime·args(int32 c, uint8 **v) @@ -214,9 +214,9 @@ runtime·goenvs_unix(void) 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 @@ runtime·getenv(int8 *s) 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 2c4579ff082adb77bf5abb1d58680a9754186554..3b4bbedf131b366e7e1ff57852bf9db408b9b547 100644 --- a/src/pkg/syscall/Makefile +++ b/src/pkg/syscall/Makefile @@ -18,6 +18,7 @@ GOFILES=\ GOFILES_freebsd=\ bpf_bsd.go\ + env_unix.go\ exec_unix.go\ route_bsd.go\ route_freebsd.go\ @@ -27,6 +28,7 @@ GOFILES_freebsd=\ GOFILES_darwin=\ bpf_bsd.go\ + env_unix.go\ exec_unix.go\ route_bsd.go\ route_darwin.go\ @@ -35,6 +37,7 @@ GOFILES_darwin=\ syscall_unix.go\ GOFILES_linux=\ + env_unix.go\ exec_unix.go\ lsf_linux.go\ netlink_linux.go\ @@ -44,6 +47,7 @@ GOFILES_linux=\ GOFILES_openbsd=\ bpf_bsd.go\ + env_unix.go\ exec_unix.go\ route_bsd.go\ route_openbsd.go\ @@ -52,12 +56,14 @@ GOFILES_openbsd=\ 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 0000000000000000000000000000000000000000..7a6ea90bf13a5a5db79753d3c5d301b50f075547 --- /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 0000000000000000000000000000000000000000..94a64713072ec6a1374ccc93fa243e992df7a200 --- /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 0000000000000000000000000000000000000000..8c1c4271a28319e4c4ec88f92a05f450f0c88e45 --- /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 9d02d127f21e046435011b40e7b1fe01e10a4fe0..c8ffd09d588b5a96b8be73d75bc23b1e1a413187 100644 --- a/src/pkg/syscall/syscall_bsd.go +++ b/src/pkg/syscall/syscall_bsd.go @@ -137,11 +137,6 @@ func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, 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 52a7dc26bfb50268ec03463c108c2fbd6e3aa1b1..bae7f20e1ccabff532e75b71128c635945ae30ba 100644 --- a/src/pkg/syscall/syscall_linux.go +++ b/src/pkg/syscall/syscall_linux.go @@ -184,12 +184,6 @@ func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, 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 0409a040d936e56587c0f8956af54ba48d79163d..2005d812a5262b0741d908e1c6525202a55ec369 100644 --- a/src/pkg/syscall/syscall_plan9.go +++ b/src/pkg/syscall/syscall_plan9.go @@ -163,11 +163,6 @@ func Pipe(p []int) (err Error) { 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 db8d3bc21efcc1c389ac5deac1236d978314e839..2c0cc5401f69f1ca9691a206d28410b6a027dd1f 100644 --- a/src/pkg/syscall/syscall_windows.go +++ b/src/pkg/syscall/syscall_windows.go @@ -110,7 +110,6 @@ func NewCallback(fn interface{}) uintptr //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 57010243e7445276972f4cd2db2e953db39fffd8..7970d3e050d4030f8d2d870df36afce6f5b7ddc2 100644 --- a/src/pkg/syscall/zsyscall_windows_386.go +++ b/src/pkg/syscall/zsyscall_windows_386.go @@ -41,7 +41,6 @@ var ( 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 @@ func GetSystemTimeAsFileTime(time *Filetime) { 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 56d4399158a03c5cd3f3cf3c1ab263d3afb04c1d..49c5fb0fe95347bf511a547253b251f6bd675ec1 100644 --- a/src/pkg/syscall/zsyscall_windows_amd64.go +++ b/src/pkg/syscall/zsyscall_windows_amd64.go @@ -41,7 +41,6 @@ var ( 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 @@ func GetSystemTimeAsFileTime(time *Filetime) { 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)