summaryrefslogtreecommitdiff
path: root/src/lib/os
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/os')
-rw-r--r--src/lib/os/env.go66
-rw-r--r--src/lib/os/exec.go3
2 files changed, 59 insertions, 10 deletions
diff --git a/src/lib/os/env.go b/src/lib/os/env.go
index dd4970dea..4c53a9ad9 100644
--- a/src/lib/os/env.go
+++ b/src/lib/os/env.go
@@ -3,25 +3,71 @@
// license that can be found in the LICENSE file.
// Environment variables.
-// Setenv doesn't exist yet: don't have the run-time hooks yet
package os
-import os "os"
+import (
+ "once";
+ "os";
+)
var (
ENOENV = NewError("no such environment variable");
+
+ env map[string] string;
)
-func Getenv(s string) (v string, err *Error) {
- n := len(s);
- if n == 0 {
- return "", EINVAL
+func copyenv() {
+ env = make(map[string] string);
+ for i, s := range sys.Envs {
+ for j := 0; j < len(s); j++ {
+ if s[j] == '=' {
+ env[s[0:j]] = s[j+1:len(s)];
+ break;
+ }
+ }
+ }
+}
+
+func Getenv(key string) (value string, err *Error) {
+ once.Do(copyenv);
+
+ if len(key) == 0 {
+ return "", EINVAL;
+ }
+ v, ok := env[key];
+ if !ok {
+ return "", ENOENV;
+ }
+ return v, nil;
+}
+
+func Setenv(key, value string) *Error {
+ once.Do(copyenv);
+
+ if len(key) == 0 {
+ return EINVAL;
}
- for i, e := range sys.Envs {
- if len(e) > n && e[n] == '=' && e[0:n] == s {
- return e[n+1:len(e)], nil
+ env[key] = value;
+ return nil;
+}
+
+func Clearenv() {
+ once.Do(copyenv); // prevent copyenv in Getenv/Setenv
+ env = make(map[string] string);
+}
+
+func Environ() []string {
+ once.Do(copyenv);
+ a := make([]string, len(env));
+ i := 0;
+ for k, v := range(env) {
+ // check i < len(a) for safety,
+ // in case env is changing underfoot.
+ if i < len(a) {
+ a[i] = k + "=" + v;
+ i++;
}
}
- return "", ENOENV
+ return a[0:i];
}
diff --git a/src/lib/os/exec.go b/src/lib/os/exec.go
index 0ce51773c..44e70cbbe 100644
--- a/src/lib/os/exec.go
+++ b/src/lib/os/exec.go
@@ -27,6 +27,9 @@ func ForkExec(argv0 string, argv []string, envv []string, fd []*FD)
}
func Exec(argv0 string, argv []string, envv []string) *Error {
+ if envv == nil {
+ envv = Environ();
+ }
e := syscall.Exec(argv0, argv, envv);
return ErrnoToError(e);
}