2011-11-14 12:06:50 -07:00
|
|
|
// 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.
|
|
|
|
|
all: merge NaCl branch (part 1)
See golang.org/s/go13nacl for design overview.
This CL is the mostly mechanical changes from rsc's Go 1.2 based NaCl branch, specifically 39cb35750369 to 500771b477cf from https://code.google.com/r/rsc-go13nacl. This CL does not include working NaCl support, there are probably two or three more large merges to come.
CL 15750044 is not included as it involves more invasive changes to the linker which will need to be merged separately.
The exact change lists included are
15050047: syscall: support for Native Client
15360044: syscall: unzip implementation for Native Client
15370044: syscall: Native Client SRPC implementation
15400047: cmd/dist, cmd/go, go/build, test: support for Native Client
15410048: runtime: support for Native Client
15410049: syscall: file descriptor table for Native Client
15410050: syscall: in-memory file system for Native Client
15440048: all: update +build lines for Native Client port
15540045: cmd/6g, cmd/8g, cmd/gc: support for Native Client
15570045: os: support for Native Client
15680044: crypto/..., hash/crc32, reflect, sync/atomic: support for amd64p32
15690044: net: support for Native Client
15690048: runtime: support for fake time like on Go Playground
15690051: build: disable various tests on Native Client
LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/68150047
2014-02-25 07:47:42 -07:00
|
|
|
// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
|
2011-11-14 12:06:50 -07:00
|
|
|
|
|
|
|
// Unix environment variables.
|
|
|
|
|
|
|
|
package syscall
|
|
|
|
|
|
|
|
import "sync"
|
|
|
|
|
2012-01-09 17:51:20 -07:00
|
|
|
var (
|
|
|
|
// envOnce guards initialization by copyenv, which populates env.
|
|
|
|
envOnce sync.Once
|
2011-11-14 12:06:50 -07:00
|
|
|
|
2012-01-09 17:51:20 -07:00
|
|
|
// envLock guards env and envs.
|
|
|
|
envLock sync.RWMutex
|
|
|
|
|
|
|
|
// env maps from an environment variable to its first occurrence in envs.
|
|
|
|
env map[string]int
|
|
|
|
|
2014-10-01 12:17:15 -06:00
|
|
|
// envs is provided by the runtime. elements are expected to
|
|
|
|
// be of the form "key=value". An empty string means deleted
|
|
|
|
// (or a duplicate to be ignored).
|
cmd/cc, cmd/ld, runtime: disallow conservative data/bss objects
In linker, refuse to write conservative (array of pointers) as the
garbage collection type for any variable in the data/bss GC program.
In the linker, attach the Go type to an already-read C declaration
during dedup. This gives us Go types for C globals for free as long
as the cmd/dist-generated Go code contains the declaration.
(Most runtime C declarations have a corresponding Go declaration.
Both are bss declarations and so the linker dedups them.)
In cmd/dist, add a few more C files to the auto-Go-declaration list
in order to get Go type information for the C declarations into the linker.
In C compiler, mark all non-pointer-containing global declarations
and all string data as NOPTR. This allows them to exist in C files
without any corresponding Go declaration. Count C function pointers
as "non-pointer-containing", since we have no heap-allocated C functions.
In runtime, add NOPTR to the remaining pointer-containing declarations,
none of which refer to Go heap objects.
In runtime, also move os.Args and syscall.envs data into runtime-owned
variables. Otherwise, in programs that do not import os or syscall, the
runtime variables named os.Args and syscall.envs will be missing type
information.
I believe that this CL eliminates the final source of conservative GC scanning
in non-SWIG Go programs, and therefore...
Fixes #909.
LGTM=iant
R=iant
CC=golang-codereviews
https://golang.org/cl/149770043
2014-09-24 14:55:26 -06:00
|
|
|
envs []string = runtime_envs()
|
2012-01-09 17:51:20 -07:00
|
|
|
)
|
|
|
|
|
cmd/cc, cmd/ld, runtime: disallow conservative data/bss objects
In linker, refuse to write conservative (array of pointers) as the
garbage collection type for any variable in the data/bss GC program.
In the linker, attach the Go type to an already-read C declaration
during dedup. This gives us Go types for C globals for free as long
as the cmd/dist-generated Go code contains the declaration.
(Most runtime C declarations have a corresponding Go declaration.
Both are bss declarations and so the linker dedups them.)
In cmd/dist, add a few more C files to the auto-Go-declaration list
in order to get Go type information for the C declarations into the linker.
In C compiler, mark all non-pointer-containing global declarations
and all string data as NOPTR. This allows them to exist in C files
without any corresponding Go declaration. Count C function pointers
as "non-pointer-containing", since we have no heap-allocated C functions.
In runtime, add NOPTR to the remaining pointer-containing declarations,
none of which refer to Go heap objects.
In runtime, also move os.Args and syscall.envs data into runtime-owned
variables. Otherwise, in programs that do not import os or syscall, the
runtime variables named os.Args and syscall.envs will be missing type
information.
I believe that this CL eliminates the final source of conservative GC scanning
in non-SWIG Go programs, and therefore...
Fixes #909.
LGTM=iant
R=iant
CC=golang-codereviews
https://golang.org/cl/149770043
2014-09-24 14:55:26 -06:00
|
|
|
func runtime_envs() []string // in package runtime
|
|
|
|
|
2014-10-01 12:17:15 -06:00
|
|
|
// setenv_c and unsetenv_c are provided by the runtime but are no-ops
|
|
|
|
// if cgo isn't loaded.
|
2011-11-14 12:06:50 -07:00
|
|
|
func setenv_c(k, v string)
|
2014-10-01 12:17:15 -06:00
|
|
|
func unsetenv_c(k string)
|
2011-11-14 12:06:50 -07:00
|
|
|
|
|
|
|
func copyenv() {
|
2012-01-09 17:51:20 -07:00
|
|
|
env = make(map[string]int)
|
|
|
|
for i, s := range envs {
|
2011-11-14 12:06:50 -07:00
|
|
|
for j := 0; j < len(s); j++ {
|
|
|
|
if s[j] == '=' {
|
2012-01-09 17:51:20 -07:00
|
|
|
key := s[:j]
|
|
|
|
if _, ok := env[key]; !ok {
|
2014-10-01 12:17:15 -06:00
|
|
|
env[key] = i // first mention of key
|
|
|
|
} else {
|
|
|
|
// Clear duplicate keys. This permits Unsetenv to
|
|
|
|
// safely delete only the first item without
|
|
|
|
// worrying about unshadowing a later one,
|
|
|
|
// which might be a security problem.
|
|
|
|
envs[i] = ""
|
2012-01-09 17:51:20 -07:00
|
|
|
}
|
2011-11-14 12:06:50 -07:00
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-01 12:17:15 -06:00
|
|
|
func Unsetenv(key string) error {
|
|
|
|
envOnce.Do(copyenv)
|
|
|
|
|
|
|
|
envLock.Lock()
|
|
|
|
defer envLock.Unlock()
|
|
|
|
|
|
|
|
if i, ok := env[key]; ok {
|
|
|
|
envs[i] = ""
|
|
|
|
delete(env, key)
|
|
|
|
}
|
|
|
|
unsetenv_c(key)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2011-11-14 12:06:50 -07:00
|
|
|
func Getenv(key string) (value string, found bool) {
|
|
|
|
envOnce.Do(copyenv)
|
|
|
|
if len(key) == 0 {
|
|
|
|
return "", false
|
|
|
|
}
|
|
|
|
|
|
|
|
envLock.RLock()
|
|
|
|
defer envLock.RUnlock()
|
|
|
|
|
2012-01-09 17:51:20 -07:00
|
|
|
i, ok := env[key]
|
2011-11-14 12:06:50 -07:00
|
|
|
if !ok {
|
|
|
|
return "", false
|
|
|
|
}
|
2012-01-09 17:51:20 -07:00
|
|
|
s := envs[i]
|
|
|
|
for i := 0; i < len(s); i++ {
|
|
|
|
if s[i] == '=' {
|
|
|
|
return s[i+1:], true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return "", false
|
2011-11-14 12:06:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
func Setenv(key, value string) error {
|
|
|
|
envOnce.Do(copyenv)
|
|
|
|
if len(key) == 0 {
|
|
|
|
return EINVAL
|
|
|
|
}
|
2013-02-08 11:45:46 -07:00
|
|
|
for i := 0; i < len(key); i++ {
|
|
|
|
if key[i] == '=' || key[i] == 0 {
|
|
|
|
return EINVAL
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for i := 0; i < len(value); i++ {
|
|
|
|
if value[i] == 0 {
|
|
|
|
return EINVAL
|
|
|
|
}
|
|
|
|
}
|
2011-11-14 12:06:50 -07:00
|
|
|
|
|
|
|
envLock.Lock()
|
|
|
|
defer envLock.Unlock()
|
|
|
|
|
2012-01-09 17:51:20 -07:00
|
|
|
i, ok := env[key]
|
|
|
|
kv := key + "=" + value
|
|
|
|
if ok {
|
|
|
|
envs[i] = kv
|
|
|
|
} else {
|
|
|
|
i = len(envs)
|
|
|
|
envs = append(envs, kv)
|
|
|
|
}
|
|
|
|
env[key] = i
|
|
|
|
setenv_c(key, value)
|
2011-11-14 12:06:50 -07:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func Clearenv() {
|
|
|
|
envOnce.Do(copyenv) // prevent copyenv in Getenv/Setenv
|
|
|
|
|
|
|
|
envLock.Lock()
|
|
|
|
defer envLock.Unlock()
|
|
|
|
|
2014-10-01 12:17:15 -06:00
|
|
|
for k := range env {
|
|
|
|
unsetenv_c(k)
|
|
|
|
}
|
2012-01-09 17:51:20 -07:00
|
|
|
env = make(map[string]int)
|
|
|
|
envs = []string{}
|
2011-11-14 12:06:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
func Environ() []string {
|
|
|
|
envOnce.Do(copyenv)
|
|
|
|
envLock.RLock()
|
|
|
|
defer envLock.RUnlock()
|
2014-10-01 12:17:15 -06:00
|
|
|
a := make([]string, 0, len(envs))
|
|
|
|
for _, env := range envs {
|
|
|
|
if env != "" {
|
|
|
|
a = append(a, env)
|
|
|
|
}
|
|
|
|
}
|
2011-11-14 12:06:50 -07:00
|
|
|
return a
|
|
|
|
}
|