Source file
src/runtime/env_plan9.go
1
2
3
4
5 package runtime
6
7 import "unsafe"
8
9 const (
10
11 envDir = "/env/"
12
13 dirBufSize = 4096
14
15 envBufSize = 128
16
17 nameOffset = 39
18 )
19
20
21
22
23
24
25
26
27
28
29 func goenvs() {
30 buf := make([]byte, envBufSize)
31 copy(buf, envDir)
32 dirfd := open(&buf[0], _OREAD, 0)
33 if dirfd < 0 {
34 return
35 }
36 defer closefd(dirfd)
37 dofiles(dirfd, func(name []byte) {
38 name = append(name, 0)
39 buf = buf[:len(envDir)]
40 copy(buf, envDir)
41 buf = append(buf, name...)
42 fd := open(&buf[0], _OREAD, 0)
43 if fd < 0 {
44 return
45 }
46 defer closefd(fd)
47 n := len(buf)
48 r := 0
49 for {
50 r = int(pread(fd, unsafe.Pointer(&buf[0]), int32(n), 0))
51 if r < n {
52 break
53 }
54 n = int(seek(fd, 0, 2)) + 1
55 if len(buf) < n {
56 buf = make([]byte, n)
57 }
58 }
59 if r <= 0 {
60 r = 0
61 } else if buf[r-1] == 0 {
62 r--
63 }
64 name[len(name)-1] = '='
65 env := make([]byte, len(name)+r)
66 copy(env, name)
67 copy(env[len(name):], buf[:r])
68 envs = append(envs, string(env))
69 })
70 }
71
72
73
74
75 func dofiles(dirfd int32, f func([]byte)) {
76 dirbuf := new([dirBufSize]byte)
77
78 var off int64 = 0
79 for {
80 n := pread(dirfd, unsafe.Pointer(&dirbuf[0]), int32(dirBufSize), off)
81 if n <= 0 {
82 return
83 }
84 for b := dirbuf[:n]; len(b) > 0; {
85 var name []byte
86 name, b = gdirname(b)
87 if name == nil {
88 return
89 }
90 f(name)
91 }
92 off += int64(n)
93 }
94 }
95
96
97
98
99
100 func gdirname(buf []byte) (name []byte, rest []byte) {
101 if 2+nameOffset+2 > len(buf) {
102 return
103 }
104 entryLen, buf := gbit16(buf)
105 if entryLen > len(buf) {
106 return
107 }
108 n, b := gbit16(buf[nameOffset:])
109 if n > len(b) {
110 return
111 }
112 name = b[:n]
113 rest = buf[entryLen:]
114 return
115 }
116
117
118
119
120 func gbit16(b []byte) (int, []byte) {
121 return int(b[0]) | int(b[1])<<8, b[2:]
122 }
123
View as plain text