Skip to content

Commit 289fceb

Browse files
committed
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).
1 parent e12da15 commit 289fceb

File tree

6 files changed

+142
-146
lines changed

6 files changed

+142
-146
lines changed

src/syscall/env_libc.go

+52
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,57 @@ func Environ() []string {
5555
return envs
5656
}
5757

58+
func Getenv(key string) (value string, found bool) {
59+
data := cstring(key)
60+
raw := libc_getenv(&data[0])
61+
if raw == nil {
62+
return "", false
63+
}
64+
65+
ptr := uintptr(unsafe.Pointer(raw))
66+
for size := uintptr(0); ; size++ {
67+
v := *(*byte)(unsafe.Pointer(ptr))
68+
if v == 0 {
69+
src := *(*[]byte)(unsafe.Pointer(&sliceHeader{buf: raw, len: size, cap: size}))
70+
return string(src), true
71+
}
72+
ptr += unsafe.Sizeof(byte(0))
73+
}
74+
}
75+
76+
func Setenv(key, val string) (err error) {
77+
if len(key) == 0 {
78+
return EINVAL
79+
}
80+
for i := 0; i < len(key); i++ {
81+
if key[i] == '=' || key[i] == 0 {
82+
return EINVAL
83+
}
84+
}
85+
for i := 0; i < len(val); i++ {
86+
if val[i] == 0 {
87+
return EINVAL
88+
}
89+
}
90+
runtimeSetenv(key, val)
91+
return
92+
}
93+
94+
func Unsetenv(key string) (err error) {
95+
runtimeUnsetenv(key)
96+
return
97+
}
98+
99+
func Clearenv() {
100+
for _, s := range Environ() {
101+
for j := 0; j < len(s); j++ {
102+
if s[j] == '=' {
103+
Unsetenv(s[0:j])
104+
break
105+
}
106+
}
107+
}
108+
}
109+
58110
//go:extern environ
59111
var libc_environ *unsafe.Pointer

src/syscall/env_nonhosted.go

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//go:build baremetal || js || wasm_unknown
2+
3+
package syscall
4+
5+
func Environ() []string {
6+
env := runtime_envs()
7+
envCopy := make([]string, len(env))
8+
copy(envCopy, env)
9+
return envCopy
10+
}
11+
12+
func Getenv(key string) (value string, found bool) {
13+
env := runtime_envs()
14+
for _, keyval := range env {
15+
// Split at '=' character.
16+
var k, v string
17+
for i := 0; i < len(keyval); i++ {
18+
if keyval[i] == '=' {
19+
k = keyval[:i]
20+
v = keyval[i+1:]
21+
}
22+
}
23+
if k == key {
24+
return v, true
25+
}
26+
}
27+
return "", false
28+
}
29+
30+
func Setenv(key, val string) (err error) {
31+
// stub for now
32+
return ENOSYS
33+
}
34+
35+
func Unsetenv(key string) (err error) {
36+
// stub for now
37+
return ENOSYS
38+
}
39+
40+
func Clearenv() (err error) {
41+
// stub for now
42+
return ENOSYS
43+
}
44+
45+
func runtime_envs() []string

src/syscall/env_wasip2.go

+45
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,55 @@
22

33
package syscall
44

5+
import (
6+
"internal/wasi/cli/v0.2.0/environment"
7+
)
8+
9+
var libc_envs map[string]string
10+
11+
func populateEnvironment() {
12+
libc_envs = make(map[string]string)
13+
for _, kv := range environment.GetEnvironment().Slice() {
14+
libc_envs[kv[0]] = kv[1]
15+
}
16+
}
17+
518
func Environ() []string {
619
var env []string
720
for k, v := range libc_envs {
821
env = append(env, k+"="+v)
922
}
1023
return env
1124
}
25+
26+
func Getenv(key string) (value string, found bool) {
27+
value, found = libc_envs[key]
28+
return
29+
}
30+
31+
func Setenv(key, val string) (err error) {
32+
if len(key) == 0 {
33+
return EINVAL
34+
}
35+
for i := 0; i < len(key); i++ {
36+
if key[i] == '=' || key[i] == 0 {
37+
return EINVAL
38+
}
39+
}
40+
for i := 0; i < len(val); i++ {
41+
if val[i] == 0 {
42+
return EINVAL
43+
}
44+
}
45+
libc_envs[key] = val
46+
return nil
47+
}
48+
49+
func Unsetenv(key string) (err error) {
50+
delete(libc_envs, key)
51+
return nil
52+
}
53+
54+
func Clearenv() {
55+
clear(libc_envs)
56+
}

src/syscall/libc_wasip2.go

-52
Original file line numberDiff line numberDiff line change
@@ -1227,58 +1227,6 @@ func p2fileTypeToStatType(t types.DescriptorType) uint32 {
12271227
return 0
12281228
}
12291229

1230-
var libc_envs map[string]string
1231-
1232-
func populateEnvironment() {
1233-
libc_envs = make(map[string]string)
1234-
for _, kv := range environment.GetEnvironment().Slice() {
1235-
libc_envs[kv[0]] = kv[1]
1236-
}
1237-
}
1238-
1239-
// char * getenv(const char *name);
1240-
//
1241-
//export getenv
1242-
func getenv(key *byte) *byte {
1243-
k := goString(key)
1244-
1245-
v, ok := libc_envs[k]
1246-
if !ok {
1247-
return nil
1248-
}
1249-
1250-
// The new allocation is zero-filled; allocating an extra byte and then
1251-
// copying the data over will leave the last byte untouched,
1252-
// null-terminating the string.
1253-
vbytes := make([]byte, len(v)+1)
1254-
copy(vbytes, v)
1255-
return unsafe.SliceData(vbytes)
1256-
}
1257-
1258-
// int setenv(const char *name, const char *value, int overwrite);
1259-
//
1260-
//export setenv
1261-
func setenv(key, value *byte, overwrite int) int {
1262-
k := goString(key)
1263-
if _, ok := libc_envs[k]; ok && overwrite == 0 {
1264-
return 0
1265-
}
1266-
1267-
v := goString(value)
1268-
libc_envs[k] = v
1269-
1270-
return 0
1271-
}
1272-
1273-
// int unsetenv(const char *name);
1274-
//
1275-
//export unsetenv
1276-
func unsetenv(key *byte) int {
1277-
k := goString(key)
1278-
delete(libc_envs, k)
1279-
return 0
1280-
}
1281-
12821230
// void arc4random_buf (void *, size_t);
12831231
//
12841232
//export arc4random_buf

src/syscall/syscall_libc.go

-52
Original file line numberDiff line numberDiff line change
@@ -238,58 +238,6 @@ func Wait4(pid int, wstatus *WaitStatus, options int, rusage uintptr) (wpid int,
238238
return 0, ENOSYS // TODO
239239
}
240240

241-
func Getenv(key string) (value string, found bool) {
242-
data := cstring(key)
243-
raw := libc_getenv(&data[0])
244-
if raw == nil {
245-
return "", false
246-
}
247-
248-
ptr := uintptr(unsafe.Pointer(raw))
249-
for size := uintptr(0); ; size++ {
250-
v := *(*byte)(unsafe.Pointer(ptr))
251-
if v == 0 {
252-
src := *(*[]byte)(unsafe.Pointer(&sliceHeader{buf: raw, len: size, cap: size}))
253-
return string(src), true
254-
}
255-
ptr += unsafe.Sizeof(byte(0))
256-
}
257-
}
258-
259-
func Setenv(key, val string) (err error) {
260-
if len(key) == 0 {
261-
return EINVAL
262-
}
263-
for i := 0; i < len(key); i++ {
264-
if key[i] == '=' || key[i] == 0 {
265-
return EINVAL
266-
}
267-
}
268-
for i := 0; i < len(val); i++ {
269-
if val[i] == 0 {
270-
return EINVAL
271-
}
272-
}
273-
runtimeSetenv(key, val)
274-
return
275-
}
276-
277-
func Unsetenv(key string) (err error) {
278-
runtimeUnsetenv(key)
279-
return
280-
}
281-
282-
func Clearenv() {
283-
for _, s := range Environ() {
284-
for j := 0; j < len(s); j++ {
285-
if s[j] == '=' {
286-
Unsetenv(s[0:j])
287-
break
288-
}
289-
}
290-
}
291-
}
292-
293241
func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
294242
addr := libc_mmap(nil, uintptr(length), int32(prot), int32(flags), int32(fd), uintptr(offset))
295243
if addr == unsafe.Pointer(^uintptr(0)) {

src/syscall/syscall_nonhosted.go

-42
Original file line numberDiff line numberDiff line change
@@ -87,48 +87,6 @@ const (
8787
MAP_ANONYMOUS = MAP_ANON
8888
)
8989

90-
func runtime_envs() []string
91-
92-
func Getenv(key string) (value string, found bool) {
93-
env := runtime_envs()
94-
for _, keyval := range env {
95-
// Split at '=' character.
96-
var k, v string
97-
for i := 0; i < len(keyval); i++ {
98-
if keyval[i] == '=' {
99-
k = keyval[:i]
100-
v = keyval[i+1:]
101-
}
102-
}
103-
if k == key {
104-
return v, true
105-
}
106-
}
107-
return "", false
108-
}
109-
110-
func Setenv(key, val string) (err error) {
111-
// stub for now
112-
return ENOSYS
113-
}
114-
115-
func Unsetenv(key string) (err error) {
116-
// stub for now
117-
return ENOSYS
118-
}
119-
120-
func Clearenv() (err error) {
121-
// stub for now
122-
return ENOSYS
123-
}
124-
125-
func Environ() []string {
126-
env := runtime_envs()
127-
envCopy := make([]string, len(env))
128-
copy(envCopy, env)
129-
return envCopy
130-
}
131-
13290
func Open(path string, mode int, perm uint32) (fd int, err error) {
13391
return 0, ENOSYS
13492
}

0 commit comments

Comments
 (0)