From 289fceb3eaf0829d1e3b65228b95a79bd5fc9389 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Mon, 18 Nov 2024 11:43:50 +0100 Subject: syscall: refactor environment handling * Move environment functions to their own files. * Rewrite the WASIp2 version of environment variables to be much simpler (don't go through C functions). --- src/syscall/env_libc.go | 52 ++++++++++++++++++++++++++++++++++++++++ src/syscall/env_nonhosted.go | 45 ++++++++++++++++++++++++++++++++++ src/syscall/env_wasip2.go | 45 ++++++++++++++++++++++++++++++++++ src/syscall/libc_wasip2.go | 52 ---------------------------------------- src/syscall/syscall_libc.go | 52 ---------------------------------------- src/syscall/syscall_nonhosted.go | 42 -------------------------------- 6 files changed, 142 insertions(+), 146 deletions(-) create mode 100644 src/syscall/env_nonhosted.go diff --git a/src/syscall/env_libc.go b/src/syscall/env_libc.go index 4ad078dc5..fbf7d04e0 100644 --- a/src/syscall/env_libc.go +++ b/src/syscall/env_libc.go @@ -55,5 +55,57 @@ func Environ() []string { return envs } +func Getenv(key string) (value string, found bool) { + data := cstring(key) + raw := libc_getenv(&data[0]) + if raw == nil { + return "", false + } + + ptr := uintptr(unsafe.Pointer(raw)) + for size := uintptr(0); ; size++ { + v := *(*byte)(unsafe.Pointer(ptr)) + if v == 0 { + src := *(*[]byte)(unsafe.Pointer(&sliceHeader{buf: raw, len: size, cap: size})) + return string(src), true + } + ptr += unsafe.Sizeof(byte(0)) + } +} + +func Setenv(key, val string) (err error) { + if len(key) == 0 { + return EINVAL + } + for i := 0; i < len(key); i++ { + if key[i] == '=' || key[i] == 0 { + return EINVAL + } + } + for i := 0; i < len(val); i++ { + if val[i] == 0 { + return EINVAL + } + } + runtimeSetenv(key, val) + return +} + +func Unsetenv(key string) (err error) { + runtimeUnsetenv(key) + return +} + +func Clearenv() { + for _, s := range Environ() { + for j := 0; j < len(s); j++ { + if s[j] == '=' { + Unsetenv(s[0:j]) + break + } + } + } +} + //go:extern environ var libc_environ *unsafe.Pointer diff --git a/src/syscall/env_nonhosted.go b/src/syscall/env_nonhosted.go new file mode 100644 index 000000000..446ba55d2 --- /dev/null +++ b/src/syscall/env_nonhosted.go @@ -0,0 +1,45 @@ +//go:build baremetal || js || wasm_unknown + +package syscall + +func Environ() []string { + env := runtime_envs() + envCopy := make([]string, len(env)) + copy(envCopy, env) + return envCopy +} + +func Getenv(key string) (value string, found bool) { + env := runtime_envs() + for _, keyval := range env { + // Split at '=' character. + var k, v string + for i := 0; i < len(keyval); i++ { + if keyval[i] == '=' { + k = keyval[:i] + v = keyval[i+1:] + } + } + if k == key { + return v, true + } + } + return "", false +} + +func Setenv(key, val string) (err error) { + // stub for now + return ENOSYS +} + +func Unsetenv(key string) (err error) { + // stub for now + return ENOSYS +} + +func Clearenv() (err error) { + // stub for now + return ENOSYS +} + +func runtime_envs() []string diff --git a/src/syscall/env_wasip2.go b/src/syscall/env_wasip2.go index 970400d64..8064d0d28 100644 --- a/src/syscall/env_wasip2.go +++ b/src/syscall/env_wasip2.go @@ -2,6 +2,19 @@ package syscall +import ( + "internal/wasi/cli/v0.2.0/environment" +) + +var libc_envs map[string]string + +func populateEnvironment() { + libc_envs = make(map[string]string) + for _, kv := range environment.GetEnvironment().Slice() { + libc_envs[kv[0]] = kv[1] + } +} + func Environ() []string { var env []string for k, v := range libc_envs { @@ -9,3 +22,35 @@ func Environ() []string { } return env } + +func Getenv(key string) (value string, found bool) { + value, found = libc_envs[key] + return +} + +func Setenv(key, val string) (err error) { + if len(key) == 0 { + return EINVAL + } + for i := 0; i < len(key); i++ { + if key[i] == '=' || key[i] == 0 { + return EINVAL + } + } + for i := 0; i < len(val); i++ { + if val[i] == 0 { + return EINVAL + } + } + libc_envs[key] = val + return nil +} + +func Unsetenv(key string) (err error) { + delete(libc_envs, key) + return nil +} + +func Clearenv() { + clear(libc_envs) +} diff --git a/src/syscall/libc_wasip2.go b/src/syscall/libc_wasip2.go index a89e64a80..5621c1a68 100644 --- a/src/syscall/libc_wasip2.go +++ b/src/syscall/libc_wasip2.go @@ -1227,58 +1227,6 @@ func p2fileTypeToStatType(t types.DescriptorType) uint32 { return 0 } -var libc_envs map[string]string - -func populateEnvironment() { - libc_envs = make(map[string]string) - for _, kv := range environment.GetEnvironment().Slice() { - libc_envs[kv[0]] = kv[1] - } -} - -// char * getenv(const char *name); -// -//export getenv -func getenv(key *byte) *byte { - k := goString(key) - - v, ok := libc_envs[k] - if !ok { - return nil - } - - // The new allocation is zero-filled; allocating an extra byte and then - // copying the data over will leave the last byte untouched, - // null-terminating the string. - vbytes := make([]byte, len(v)+1) - copy(vbytes, v) - return unsafe.SliceData(vbytes) -} - -// int setenv(const char *name, const char *value, int overwrite); -// -//export setenv -func setenv(key, value *byte, overwrite int) int { - k := goString(key) - if _, ok := libc_envs[k]; ok && overwrite == 0 { - return 0 - } - - v := goString(value) - libc_envs[k] = v - - return 0 -} - -// int unsetenv(const char *name); -// -//export unsetenv -func unsetenv(key *byte) int { - k := goString(key) - delete(libc_envs, k) - return 0 -} - // void arc4random_buf (void *, size_t); // //export arc4random_buf diff --git a/src/syscall/syscall_libc.go b/src/syscall/syscall_libc.go index 8b032d383..d8293efde 100644 --- a/src/syscall/syscall_libc.go +++ b/src/syscall/syscall_libc.go @@ -238,58 +238,6 @@ func Wait4(pid int, wstatus *WaitStatus, options int, rusage uintptr) (wpid int, return 0, ENOSYS // TODO } -func Getenv(key string) (value string, found bool) { - data := cstring(key) - raw := libc_getenv(&data[0]) - if raw == nil { - return "", false - } - - ptr := uintptr(unsafe.Pointer(raw)) - for size := uintptr(0); ; size++ { - v := *(*byte)(unsafe.Pointer(ptr)) - if v == 0 { - src := *(*[]byte)(unsafe.Pointer(&sliceHeader{buf: raw, len: size, cap: size})) - return string(src), true - } - ptr += unsafe.Sizeof(byte(0)) - } -} - -func Setenv(key, val string) (err error) { - if len(key) == 0 { - return EINVAL - } - for i := 0; i < len(key); i++ { - if key[i] == '=' || key[i] == 0 { - return EINVAL - } - } - for i := 0; i < len(val); i++ { - if val[i] == 0 { - return EINVAL - } - } - runtimeSetenv(key, val) - return -} - -func Unsetenv(key string) (err error) { - runtimeUnsetenv(key) - return -} - -func Clearenv() { - for _, s := range Environ() { - for j := 0; j < len(s); j++ { - if s[j] == '=' { - Unsetenv(s[0:j]) - break - } - } - } -} - func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { addr := libc_mmap(nil, uintptr(length), int32(prot), int32(flags), int32(fd), uintptr(offset)) if addr == unsafe.Pointer(^uintptr(0)) { diff --git a/src/syscall/syscall_nonhosted.go b/src/syscall/syscall_nonhosted.go index b56d71af6..4867d70f6 100644 --- a/src/syscall/syscall_nonhosted.go +++ b/src/syscall/syscall_nonhosted.go @@ -87,48 +87,6 @@ const ( MAP_ANONYMOUS = MAP_ANON ) -func runtime_envs() []string - -func Getenv(key string) (value string, found bool) { - env := runtime_envs() - for _, keyval := range env { - // Split at '=' character. - var k, v string - for i := 0; i < len(keyval); i++ { - if keyval[i] == '=' { - k = keyval[:i] - v = keyval[i+1:] - } - } - if k == key { - return v, true - } - } - return "", false -} - -func Setenv(key, val string) (err error) { - // stub for now - return ENOSYS -} - -func Unsetenv(key string) (err error) { - // stub for now - return ENOSYS -} - -func Clearenv() (err error) { - // stub for now - return ENOSYS -} - -func Environ() []string { - env := runtime_envs() - envCopy := make([]string, len(env)) - copy(envCopy, env) - return envCopy -} - func Open(path string, mode int, perm uint32) (fd int, err error) { return 0, ENOSYS } -- cgit v1.2.3