os: implement and smoketest os.Setenv

Этот коммит содержится в:
Dan Kegel 2021-12-05 13:24:00 -08:00 коммит произвёл Ron Evans
родитель 93ac7cec0d
коммит cff4493ca0
5 изменённых файлов: 96 добавлений и 0 удалений

Просмотреть файл

@ -9,6 +9,18 @@ func Getenv(key string) string {
return v return v
} }
func Setenv(key, value string) error {
err := syscall.Setenv(key, value)
if err != nil {
return NewSyscallError("setenv", err)
}
return nil
}
func Unsetenv(_ string) error {
return ErrNotImplemented
}
func LookupEnv(key string) (string, bool) { func LookupEnv(key string) (string, bool) {
return syscall.Getenv(key) return syscall.Getenv(key)
} }

38
src/os/env_test.go Обычный файл
Просмотреть файл

@ -0,0 +1,38 @@
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package os_test
import (
. "os"
"reflect"
"testing"
)
func TestConsistentEnviron(t *testing.T) {
e0 := Environ()
for i := 0; i < 10; i++ {
e1 := Environ()
if !reflect.DeepEqual(e0, e1) {
t.Fatalf("environment changed")
}
}
}
func TestLookupEnv(t *testing.T) {
const smallpox = "SMALLPOX" // No one has smallpox.
value, ok := LookupEnv(smallpox) // Should not exist.
if ok || value != "" {
t.Fatalf("%s=%q", smallpox, value)
}
defer Unsetenv(smallpox)
err := Setenv(smallpox, "virus")
if err != nil {
t.Fatalf("failed to release smallpox virus")
}
_, ok = LookupEnv(smallpox)
if !ok {
t.Errorf("smallpox release failed; world remains safe but LookupEnv is broken")
}
}

27
src/runtime/env_linux.go Обычный файл
Просмотреть файл

@ -0,0 +1,27 @@
// +build linux
package runtime
// Update the C environment if cgo is loaded.
// Called from syscall.Setenv.
//go:linkname syscall_setenv_c syscall.setenv_c
func syscall_setenv_c(key string, val string) {
keydata := cstring(key)
valdata := cstring(val)
// ignore any errors
libc_setenv(&keydata[0], &valdata[0], 1)
return
}
// cstring converts a Go string to a C string.
// borrowed from syscall
func cstring(s string) []byte {
data := make([]byte, len(s)+1)
copy(data, s)
// final byte should be zero from the initial allocation
return data
}
// int setenv(const char *name, const char *val, int replace);
//export setenv
func libc_setenv(name *byte, val *byte, replace int32) int32

Просмотреть файл

@ -132,6 +132,16 @@ func Getenv(key string) (value string, found bool) {
} }
} }
func Setenv(key, val string) (err error) {
keydata := cstring(key)
valdata := cstring(val)
errCode := libc_setenv(&keydata[0], &valdata[0], 1)
if errCode != 0 {
err = getErrno()
}
return
}
func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { 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)) addr := libc_mmap(nil, uintptr(length), int32(prot), int32(flags), int32(fd), uintptr(offset))
if addr == unsafe.Pointer(^uintptr(0)) { if addr == unsafe.Pointer(^uintptr(0)) {
@ -192,6 +202,10 @@ func libc_write(fd int32, buf *byte, count uint) int
//export getenv //export getenv
func libc_getenv(name *byte) *byte func libc_getenv(name *byte) *byte
// int setenv(const char *name, const char *val, int replace);
//export setenv
func libc_setenv(name *byte, val *byte, replace int32) int32
// ssize_t read(int fd, void *buf, size_t count); // ssize_t read(int fd, void *buf, size_t count);
//export read //export read
func libc_read(fd int32, buf *byte, count uint) int func libc_read(fd int32, buf *byte, count uint) int

Просмотреть файл

@ -67,6 +67,11 @@ func Getenv(key string) (value string, found bool) {
return "", false return "", false
} }
func Setenv(key, val string) (err error) {
// stub for now
return ENOSYS
}
func Environ() []string { func Environ() []string {
env := runtime_envs() env := runtime_envs()
envCopy := make([]string, len(env)) envCopy := make([]string, len(env))