OSDN Git Service

libgo: Update to weekly.2011-11-18.
[pf3gnuchains/gcc-fork.git] / libgo / go / os / dir_unix.go
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
5 // +build darwin freebsd linux openbsd
6
7 package os
8
9 import (
10         "io"
11         "syscall"
12 )
13
14 const (
15         blockSize = 4096
16 )
17
18 // Readdirnames reads and returns a slice of names from the directory f.
19 //
20 // If n > 0, Readdirnames returns at most n names. In this case, if
21 // Readdirnames returns an empty slice, it will return a non-nil error
22 // explaining why. At the end of a directory, the error is io.EOF.
23 //
24 // If n <= 0, Readdirnames returns all the names from the directory in
25 // a single slice. In this case, if Readdirnames succeeds (reads all
26 // the way to the end of the directory), it returns the slice and a
27 // nil error. If it encounters an error before the end of the
28 // directory, Readdirnames returns the names read until that point and
29 // a non-nil error.
30 func (f *File) Readdirnames(n int) (names []string, err error) {
31         // If this file has no dirinfo, create one.
32         if f.dirinfo == nil {
33                 f.dirinfo = new(dirInfo)
34                 // The buffer must be at least a block long.
35                 f.dirinfo.buf = make([]byte, blockSize)
36         }
37         d := f.dirinfo
38
39         size := n
40         if size <= 0 {
41                 size = 100
42                 n = -1
43         }
44
45         names = make([]string, 0, size) // Empty with room to grow.
46         for n != 0 {
47                 // Refill the buffer if necessary
48                 if d.bufp >= d.nbuf {
49                         d.bufp = 0
50                         var errno error
51                         d.nbuf, errno = syscall.ReadDirent(f.fd, d.buf)
52                         if errno != nil {
53                                 return names, NewSyscallError("readdirent", errno)
54                         }
55                         if d.nbuf <= 0 {
56                                 break // EOF
57                         }
58                 }
59
60                 // Drain the buffer
61                 var nb, nc int
62                 nb, nc, names = syscall.ParseDirent(d.buf[d.bufp:d.nbuf], n, names)
63                 d.bufp += nb
64                 n -= nc
65         }
66         if n >= 0 && len(names) == 0 {
67                 return names, io.EOF
68         }
69         return names, nil
70 }