OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [os/] [dir_plan9.go] - Blame information for rev 867

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.