]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgo/go/os/dir_plan9.go
libgo: Update to current sources.
[thirdparty/gcc.git] / libgo / go / os / dir_plan9.go
CommitLineData
405ca104
ILT
1// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package os
6
7import (
2fd401c8
ILT
8 "errors"
9 "io"
405ca104
ILT
10 "syscall"
11)
12
501699af
ILT
13var errShortStat = errors.New("short stat message")
14var errBadStat = errors.New("bad stat message format")
15
af92e385 16func (file *File) readdir(n int) (fi []FileInfo, err error) {
405ca104
ILT
17 // If this file has no dirinfo, create one.
18 if file.dirinfo == nil {
9ff56c95 19 file.dirinfo = new(dirInfo)
405ca104 20 }
9ff56c95 21 d := file.dirinfo
adb0401d
ILT
22 size := n
23 if size <= 0 {
405ca104 24 size = 100
adb0401d 25 n = -1
405ca104 26 }
9ff56c95 27 result := make([]FileInfo, 0, size) // Empty with room to grow.
adb0401d 28 for n != 0 {
9ff56c95
ILT
29 // Refill the buffer if necessary
30 if d.bufp >= d.nbuf {
31 d.bufp = 0
2fd401c8 32 var e error
9ff56c95 33 d.nbuf, e = file.Read(d.buf[:])
2fd401c8 34 if e != nil && e != io.EOF {
adb0401d 35 return result, &PathError{"readdir", file.name, e}
9ff56c95 36 }
2fd401c8 37 if e == io.EOF {
405ca104
ILT
38 break
39 }
9ff56c95 40 if d.nbuf < syscall.STATFIXLEN {
501699af 41 return result, &PathError{"readdir", file.name, errShortStat}
9ff56c95 42 }
405ca104
ILT
43 }
44
9ff56c95
ILT
45 // Get a record from buffer
46 m, _ := gbit16(d.buf[d.bufp:])
47 m += 2
48 if m < syscall.STATFIXLEN {
501699af 49 return result, &PathError{"readdir", file.name, errShortStat}
405ca104 50 }
4ccad563 51 dir, e := unmarshalDir(d.buf[d.bufp : d.bufp+int(m)])
9ff56c95 52 if e != nil {
adb0401d 53 return result, &PathError{"readdir", file.name, e}
405ca104 54 }
9a0e3259 55 result = append(result, fileInfoFromStat(dir))
405ca104 56
9ff56c95 57 d.bufp += int(m)
adb0401d 58 n--
9ff56c95 59 }
405ca104 60
adb0401d 61 if n >= 0 && len(result) == 0 {
2fd401c8 62 return result, io.EOF
405ca104 63 }
adb0401d
ILT
64 return result, nil
65}
405ca104 66
af92e385 67func (file *File) readdirnames(n int) (names []string, err error) {
adb0401d 68 fi, err := file.Readdir(n)
405ca104 69 names = make([]string, len(fi))
9ff56c95 70 for i := range fi {
9a0e3259 71 names[i] = fi[i].Name()
405ca104 72 }
405ca104
ILT
73 return
74}
75
4ccad563 76type dir struct {
405ca104
ILT
77 // system-modified data
78 Type uint16 // server type
79 Dev uint32 // server subtype
80 // file data
4ccad563 81 Qid qid // unique id from server
405ca104
ILT
82 Mode uint32 // permissions
83 Atime uint32 // last read time
84 Mtime uint32 // last write time
85 Length uint64 // file length
86 Name string // last element of path
87 Uid string // owner name
88 Gid string // group name
89 Muid string // last modifier name
90}
91
4ccad563 92type qid struct {
405ca104
ILT
93 Path uint64 // the file server's unique identification for the file
94 Vers uint32 // version number for given Path
95 Type uint8 // the type of the file (syscall.QTDIR for example)
96}
97
4ccad563 98var nullDir = dir{
405ca104
ILT
99 ^uint16(0),
100 ^uint32(0),
4ccad563 101 qid{^uint64(0), ^uint32(0), ^uint8(0)},
405ca104
ILT
102 ^uint32(0),
103 ^uint32(0),
104 ^uint32(0),
105 ^uint64(0),
106 "",
107 "",
108 "",
109 "",
110}
111
112// Null assigns members of d with special "don't care" values indicating
113// they should not be written by syscall.Wstat.
4ccad563 114func (d *dir) Null() {
405ca104
ILT
115 *d = nullDir
116}
117
118// pdir appends a 9P Stat message based on the contents of Dir d to a byte slice b.
4ccad563 119func pdir(b []byte, d *dir) []byte {
405ca104
ILT
120 n := len(b)
121 b = pbit16(b, 0) // length, filled in later
122 b = pbit16(b, d.Type)
123 b = pbit32(b, d.Dev)
124 b = pqid(b, d.Qid)
125 b = pbit32(b, d.Mode)
126 b = pbit32(b, d.Atime)
127 b = pbit32(b, d.Mtime)
128 b = pbit64(b, d.Length)
129 b = pstring(b, d.Name)
130 b = pstring(b, d.Uid)
131 b = pstring(b, d.Gid)
132 b = pstring(b, d.Muid)
133 pbit16(b[0:n], uint16(len(b)-(n+2)))
134 return b
135}
136
4ccad563
ILT
137// unmarshalDir reads a 9P Stat message from a 9P protocol message stored in b,
138// returning the corresponding dir struct.
139func unmarshalDir(b []byte) (d *dir, err error) {
405ca104
ILT
140 n := uint16(0)
141 n, b = gbit16(b)
142
143 if int(n) != len(b) {
501699af 144 return nil, errBadStat
405ca104
ILT
145 }
146
4ccad563 147 d = new(dir)
405ca104
ILT
148 d.Type, b = gbit16(b)
149 d.Dev, b = gbit32(b)
150 d.Qid, b = gqid(b)
151 d.Mode, b = gbit32(b)
152 d.Atime, b = gbit32(b)
153 d.Mtime, b = gbit32(b)
154 d.Length, b = gbit64(b)
155 d.Name, b = gstring(b)
156 d.Uid, b = gstring(b)
157 d.Gid, b = gstring(b)
158 d.Muid, b = gstring(b)
159
160 if len(b) != 0 {
501699af 161 return nil, errBadStat
405ca104
ILT
162 }
163
164 return d, nil
165}
166
adb0401d 167// gqid reads the qid part of a 9P Stat message from a 9P protocol message stored in b,
4ccad563
ILT
168// returning the corresponding qid struct and the remaining slice of b.
169func gqid(b []byte) (qid, []byte) {
170 var q qid
405ca104
ILT
171 q.Path, b = gbit64(b)
172 q.Vers, b = gbit32(b)
173 q.Type, b = gbit8(b)
174 return q, b
175}
176
4ccad563
ILT
177// pqid appends a qid struct q to a 9P message b.
178func pqid(b []byte, q qid) []byte {
405ca104
ILT
179 b = pbit64(b, q.Path)
180 b = pbit32(b, q.Vers)
181 b = pbit8(b, q.Type)
182 return b
183}
184
adb0401d 185// gbit8 reads a byte-sized numeric value from a 9P protocol message stored in b,
405ca104
ILT
186// returning the value and the remaining slice of b.
187func gbit8(b []byte) (uint8, []byte) {
188 return uint8(b[0]), b[1:]
189}
190
adb0401d 191// gbit16 reads a 16-bit numeric value from a 9P protocol message stored in b,
405ca104
ILT
192// returning the value and the remaining slice of b.
193func gbit16(b []byte) (uint16, []byte) {
194 return uint16(b[0]) | uint16(b[1])<<8, b[2:]
195}
196
adb0401d 197// gbit32 reads a 32-bit numeric value from a 9P protocol message stored in b,
405ca104
ILT
198// returning the value and the remaining slice of b.
199func gbit32(b []byte) (uint32, []byte) {
200 return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24, b[4:]
201}
202
adb0401d 203// gbit64 reads a 64-bit numeric value from a 9P protocol message stored in b,
405ca104
ILT
204// returning the value and the remaining slice of b.
205func gbit64(b []byte) (uint64, []byte) {
206 lo, b := gbit32(b)
207 hi, b := gbit32(b)
208 return uint64(hi)<<32 | uint64(lo), b
209}
210
adb0401d 211// gstring reads a string from a 9P protocol message stored in b,
405ca104
ILT
212// returning the value as a Go string and the remaining slice of b.
213func gstring(b []byte) (string, []byte) {
214 n, b := gbit16(b)
215 return string(b[0:n]), b[n:]
216}
217
218// pbit8 appends a byte-sized numeric value x to a 9P message b.
219func pbit8(b []byte, x uint8) []byte {
220 n := len(b)
221 if n+1 > cap(b) {
222 nb := make([]byte, n, 100+2*cap(b))
223 copy(nb, b)
224 b = nb
225 }
226 b = b[0 : n+1]
227 b[n] = x
228 return b
229}
230
231// pbit16 appends a 16-bit numeric value x to a 9P message b.
232func pbit16(b []byte, x uint16) []byte {
233 n := len(b)
234 if n+2 > cap(b) {
235 nb := make([]byte, n, 100+2*cap(b))
236 copy(nb, b)
237 b = nb
238 }
239 b = b[0 : n+2]
240 b[n] = byte(x)
241 b[n+1] = byte(x >> 8)
242 return b
243}
244
245// pbit32 appends a 32-bit numeric value x to a 9P message b.
246func pbit32(b []byte, x uint32) []byte {
247 n := len(b)
248 if n+4 > cap(b) {
249 nb := make([]byte, n, 100+2*cap(b))
250 copy(nb, b)
251 b = nb
252 }
253 b = b[0 : n+4]
254 b[n] = byte(x)
255 b[n+1] = byte(x >> 8)
256 b[n+2] = byte(x >> 16)
257 b[n+3] = byte(x >> 24)
258 return b
259}
260
261// pbit64 appends a 64-bit numeric value x to a 9P message b.
262func pbit64(b []byte, x uint64) []byte {
263 b = pbit32(b, uint32(x))
264 b = pbit32(b, uint32(x>>32))
265 return b
266}
267
268// pstring appends a Go string s to a 9P message b.
269func pstring(b []byte, s string) []byte {
270 if len(s) >= 1<<16 {
2fd401c8 271 panic(errors.New("string too long"))
405ca104
ILT
272 }
273 b = pbit16(b, uint16(len(s)))
d8f41257 274 b = append(b, s...)
405ca104
ILT
275 return b
276}