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).
This commit is contained in:
Ayke van Laethem
2024-11-18 11:43:50 +01:00
committed by Ayke
parent e12da15f7d
commit 289fceb3ea
6 changed files with 142 additions and 146 deletions
+52
View File
@@ -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
+45
View File
@@ -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
+45
View File
@@ -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)
}
-52
View File
@@ -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
-52
View File
@@ -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)) {
-42
View File
@@ -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
}