mirror of
https://github.com/golang/go
synced 2024-11-19 22:04:44 -07:00
runtime: translate env*.c to Go
In an earlier CL I wrote a separate Go-only version, but that broke Plan 9, because the Go-only version assumed a non-Plan 9 system. Translate the real ones instead. LGTM=r R=golang-codereviews, r CC=0intro, golang-codereviews, iant, khr https://golang.org/cl/140050044
This commit is contained in:
parent
2fd62a42b4
commit
50199d7b35
@ -7,4 +7,4 @@
|
||||
#pragma cgo_import_static x_cgo_setenv
|
||||
|
||||
void x_cgo_setenv(char**);
|
||||
void (*_cgo_setenv)(char**) = x_cgo_setenv;
|
||||
void (*runtime·_cgo_setenv)(char**) = x_cgo_setenv;
|
||||
|
@ -1,42 +0,0 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
#include "runtime.h"
|
||||
#include "os_GOOS.h"
|
||||
|
||||
byte*
|
||||
runtime·getenv(int8 *s)
|
||||
{
|
||||
int32 fd, n, r;
|
||||
intgo len;
|
||||
byte file[128];
|
||||
byte *p;
|
||||
static byte b[128];
|
||||
|
||||
len = runtime·findnull((byte*)s);
|
||||
if(len > sizeof file-6)
|
||||
return nil;
|
||||
|
||||
runtime·memclr(file, sizeof file);
|
||||
runtime·memmove((void*)file, (void*)"/env/", 5);
|
||||
runtime·memmove((void*)(file+5), (void*)s, len);
|
||||
|
||||
fd = runtime·open((int8*)file, OREAD, 0);
|
||||
if(fd < 0)
|
||||
return nil;
|
||||
n = runtime·seek(fd, 0, 2);
|
||||
if(runtime·strcmp((byte*)s, (byte*)"GOTRACEBACK") == 0){
|
||||
// should not call malloc
|
||||
if(n >= sizeof b)
|
||||
return nil;
|
||||
runtime·memclr(b, sizeof b);
|
||||
p = b;
|
||||
}else
|
||||
p = runtime·mallocgc(n+1, nil, 0);
|
||||
r = runtime·pread(fd, p, n, 0);
|
||||
runtime·close(fd);
|
||||
if(r < 0)
|
||||
return nil;
|
||||
return p;
|
||||
}
|
58
src/pkg/runtime/env_plan9.go
Normal file
58
src/pkg/runtime/env_plan9.go
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright 2012 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 runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func getenv(s *byte) *byte {
|
||||
val := gogetenv(gostringnocopy(s))
|
||||
if val == "" {
|
||||
return nil
|
||||
}
|
||||
// Strings found in environment are NUL-terminated.
|
||||
return &bytes(val)[0]
|
||||
}
|
||||
|
||||
var tracebackbuf [128]byte
|
||||
|
||||
func gogetenv(key string) string {
|
||||
var file [128]byte
|
||||
if len(key) > len(file)-6 {
|
||||
return ""
|
||||
}
|
||||
|
||||
copy(file[:], "/env/")
|
||||
copy(file[5:], key)
|
||||
|
||||
fd := open(&file[0], _OREAD, 0)
|
||||
if fd < 0 {
|
||||
return ""
|
||||
}
|
||||
n := seek(fd, 0, 2)
|
||||
|
||||
var p unsafe.Pointer
|
||||
|
||||
// Be sure not to allocate for $GOTRACEBACK.
|
||||
if key == "GOTRACEBACK" {
|
||||
if n >= 128 {
|
||||
return ""
|
||||
}
|
||||
p = unsafe.Pointer(&tracebackbuf[0])
|
||||
} else {
|
||||
p = gomallocgc(uintptr(n+1), nil, 0)
|
||||
}
|
||||
|
||||
r := pread(fd, p, int32(n), 0)
|
||||
close(fd)
|
||||
if r < 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
var s string
|
||||
sp := (*_string)(unsafe.Pointer(&s))
|
||||
sp.str = (*byte)(p)
|
||||
sp.len = int(r)
|
||||
return s
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
|
||||
|
||||
#include "runtime.h"
|
||||
#include "arch_GOARCH.h"
|
||||
#include "malloc.h"
|
||||
|
||||
Slice syscall·envs;
|
||||
|
||||
byte*
|
||||
runtime·getenv(int8 *s)
|
||||
{
|
||||
int32 i, j;
|
||||
intgo len;
|
||||
byte *v, *bs;
|
||||
String* envv;
|
||||
int32 envc;
|
||||
|
||||
bs = (byte*)s;
|
||||
len = runtime·findnull(bs);
|
||||
envv = (String*)syscall·envs.array;
|
||||
if(envv == nil)
|
||||
runtime·throw("getenv before env init");
|
||||
envc = syscall·envs.len;
|
||||
for(i=0; i<envc; i++){
|
||||
if(envv[i].len <= len)
|
||||
continue;
|
||||
v = envv[i].str;
|
||||
for(j=0; j<len; j++)
|
||||
if(bs[j] != v[j])
|
||||
goto nomatch;
|
||||
if(v[len] != '=')
|
||||
goto nomatch;
|
||||
return v+len+1;
|
||||
nomatch:;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
void (*_cgo_setenv)(byte**);
|
||||
|
||||
// Update the C environment if cgo is loaded.
|
||||
// Called from syscall.Setenv.
|
||||
void
|
||||
syscall·setenv_c(String k, String v)
|
||||
{
|
||||
byte *arg[2];
|
||||
|
||||
if(_cgo_setenv == nil)
|
||||
return;
|
||||
|
||||
arg[0] = runtime·mallocgc(k.len + 1, nil, 0);
|
||||
runtime·memmove(arg[0], k.str, k.len);
|
||||
arg[0][k.len] = 0;
|
||||
|
||||
arg[1] = runtime·mallocgc(v.len + 1, nil, 0);
|
||||
runtime·memmove(arg[1], v.str, v.len);
|
||||
arg[1][v.len] = 0;
|
||||
|
||||
runtime·asmcgocall((void*)_cgo_setenv, arg);
|
||||
}
|
52
src/pkg/runtime/env_posix.go
Normal file
52
src/pkg/runtime/env_posix.go
Normal file
@ -0,0 +1,52 @@
|
||||
// Copyright 2012 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.
|
||||
|
||||
// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
|
||||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func environ() []string
|
||||
|
||||
func getenv(s *byte) *byte {
|
||||
val := gogetenv(gostringnocopy(s))
|
||||
if val == "" {
|
||||
return nil
|
||||
}
|
||||
// Strings found in environment are NUL-terminated.
|
||||
return &bytes(val)[0]
|
||||
}
|
||||
|
||||
func gogetenv(key string) string {
|
||||
env := environ()
|
||||
if env == nil {
|
||||
gothrow("getenv before env init")
|
||||
}
|
||||
for _, s := range environ() {
|
||||
if len(s) > len(key) && s[len(key)] == '=' && s[:len(key)] == key {
|
||||
return s[len(key)+1:]
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var _cgo_setenv uintptr // pointer to C function
|
||||
|
||||
// Update the C environment if cgo is loaded.
|
||||
// Called from syscall.Setenv.
|
||||
func syscall_setenv_c(k string, v string) {
|
||||
if _cgo_setenv == 0 {
|
||||
return
|
||||
}
|
||||
arg := [2]unsafe.Pointer{cstring(k), cstring(v)}
|
||||
asmcgocall(unsafe.Pointer(_cgo_setenv), unsafe.Pointer(&arg))
|
||||
}
|
||||
|
||||
func cstring(s string) unsafe.Pointer {
|
||||
p := make([]byte, len(s)+1)
|
||||
sp := (*_string)(unsafe.Pointer(&s))
|
||||
memmove(unsafe.Pointer(&p[0]), unsafe.Pointer(sp.str), uintptr(len(s)))
|
||||
return unsafe.Pointer(&p[0])
|
||||
}
|
@ -149,20 +149,6 @@ func Callers(skip int, pc []uintptr) int {
|
||||
func callers(int32, *uintptr, int32) int32
|
||||
|
||||
func getgoroot() string
|
||||
func environ() []string
|
||||
|
||||
func gogetenv(key string) string {
|
||||
env := environ()
|
||||
if env == nil {
|
||||
gothrow("getenv before env init")
|
||||
}
|
||||
for _, s := range env {
|
||||
if len(s) > len(key) && s[len(key)] == '=' && s[:len(key)] == key {
|
||||
return s[len(key)+1:]
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GOROOT returns the root of the Go tree.
|
||||
// It uses the GOROOT environment variable, if set,
|
||||
|
@ -152,7 +152,6 @@ func tracebackothers(gp *g)
|
||||
func cgocallback(fn, frame unsafe.Pointer, framesize uintptr)
|
||||
func gogo(buf *gobuf)
|
||||
func gosave(buf *gobuf)
|
||||
func open(name *byte, mode, perm int32) int32
|
||||
func read(fd int32, p unsafe.Pointer, n int32) int32
|
||||
func close(fd int32) int32
|
||||
func mincore(addr unsafe.Pointer, n uintptr, dst *byte) int32
|
||||
@ -162,7 +161,6 @@ func asminit()
|
||||
func setg(gg *g)
|
||||
func exit(code int32)
|
||||
func breakpoint()
|
||||
func asmcgocall(fn, arg unsafe.Pointer)
|
||||
func nanotime() int64
|
||||
func usleep(usec uint32)
|
||||
func cputicks() int64
|
||||
@ -247,3 +245,9 @@ func getcallerpc(argp unsafe.Pointer) uintptr
|
||||
|
||||
//go:noescape
|
||||
func getcallersp(argp unsafe.Pointer) uintptr
|
||||
|
||||
//go:noescape
|
||||
func asmcgocall(fn, arg unsafe.Pointer)
|
||||
|
||||
//go:noescape
|
||||
func open(name *byte, mode, perm int32) int32
|
||||
|
@ -36,7 +36,7 @@ TEXT _seek<>(SB),NOSPLIT,$0
|
||||
// int64 seek(int32, int64, int32)
|
||||
// Convenience wrapper around _seek, the actual system call.
|
||||
TEXT runtime·seek(SB),NOSPLIT,$32
|
||||
LEAQ $ret+24(FP), AX
|
||||
LEAQ ret+24(FP), AX
|
||||
MOVL fd+0(FP), BX
|
||||
MOVQ offset+8(FP), CX
|
||||
MOVL whence+16(FP), DX
|
||||
|
@ -70,3 +70,6 @@ TEXT reflect·chanrecv(SB), NOSPLIT, $0-0
|
||||
|
||||
TEXT runtime∕debug·freeOSMemory(SB), NOSPLIT, $0-0
|
||||
JMP runtime·freeOSMemory(SB)
|
||||
|
||||
TEXT syscall·setenv_c(SB), NOSPLIT, $0-0
|
||||
JMP runtime·syscall_setenv_c(SB)
|
||||
|
Loading…
Reference in New Issue
Block a user