From c47cdfa66fe38cfad268615e093969bb136bae07 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Thu, 15 Apr 2021 23:04:05 +0200 Subject: [PATCH] runtime: implement environment variables for Linux --- main_test.go | 2 +- src/runtime/runtime.go | 5 ----- src/runtime/runtime_unix.go | 34 ++++++++++++++++++++++++++++++++++ testdata/env.go | 6 +++--- testdata/env.txt | 4 ++-- 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/main_test.go b/main_test.go index 69fe99e6..c9b02ba8 100644 --- a/main_test.go +++ b/main_test.go @@ -163,7 +163,7 @@ func runPlatTests(target string, tests []string, t *testing.T) { runTest(name, target, t, nil) }) } - if target == "wasi" || target == "" && runtime.GOOS == "darwin" { + if target == "wasi" || target == "" { t.Run("filesystem.go", func(t *testing.T) { t.Parallel() runTest("filesystem.go", target, t, nil) diff --git a/src/runtime/runtime.go b/src/runtime/runtime.go index c648e4f2..1bc09ce0 100644 --- a/src/runtime/runtime.go +++ b/src/runtime/runtime.go @@ -89,8 +89,3 @@ func AdjustTimeOffset(offset int64) { func os_sigpipe() { runtimePanic("too many writes on closed pipe") } - -//go:linkname syscall_runtime_envs syscall.runtime_envs -func syscall_runtime_envs() []string { - return nil -} diff --git a/src/runtime/runtime_unix.go b/src/runtime/runtime_unix.go index 17940f69..c0a0ec63 100644 --- a/src/runtime/runtime_unix.go +++ b/src/runtime/runtime_unix.go @@ -62,6 +62,40 @@ func runMain() { run() } +//go:extern environ +var environ *unsafe.Pointer + +//export strlen +func strlen(ptr unsafe.Pointer) uintptr + +//go:linkname syscall_runtime_envs syscall.runtime_envs +func syscall_runtime_envs() []string { + // Count how many environment variables there are. + env := environ + numEnvs := 0 + for *env != nil { + numEnvs++ + env = (*unsafe.Pointer)(unsafe.Pointer(uintptr(unsafe.Pointer(env)) + unsafe.Sizeof(environ))) + } + + // Create a string slice of all environment variables. + // This requires just a single heap allocation. + env = environ + envs := make([]string, 0, numEnvs) + for *env != nil { + ptr := *env + length := strlen(ptr) + s := _string{ + ptr: (*byte)(ptr), + length: length, + } + envs = append(envs, *(*string)(unsafe.Pointer(&s))) + env = (*unsafe.Pointer)(unsafe.Pointer(uintptr(unsafe.Pointer(env)) + unsafe.Sizeof(environ))) + } + + return envs +} + func putchar(c byte) { _putchar(int(c)) } diff --git a/testdata/env.go b/testdata/env.go index 7aa5772c..74d27194 100644 --- a/testdata/env.go +++ b/testdata/env.go @@ -5,10 +5,10 @@ import ( ) func main() { - println(os.Getenv("ENV1")) + println("ENV1:", os.Getenv("ENV1")) v, ok := os.LookupEnv("ENV2") if !ok { - panic("ENV2 not found") + println("ENV2 not found") } - println(v) + println("ENV2:", v) } diff --git a/testdata/env.txt b/testdata/env.txt index d12475f4..7aadfb7b 100644 --- a/testdata/env.txt +++ b/testdata/env.txt @@ -1,2 +1,2 @@ -VALUE1 -VALUE2 +ENV1: VALUE1 +ENV2: VALUE2