Source file src/pkg/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 netbsd openbsd
6
7 package os
8
9 import (
10 "io"
11 "syscall"
12 )
13
14 const (
15 blockSize = 4096
16 )
17
18 func (f *File) readdirnames(n int) (names []string, err error) {
19 // If this file has no dirinfo, create one.
20 if f.dirinfo == nil {
21 f.dirinfo = new(dirInfo)
22 // The buffer must be at least a block long.
23 f.dirinfo.buf = make([]byte, blockSize)
24 }
25 d := f.dirinfo
26
27 size := n
28 if size <= 0 {
29 size = 100
30 n = -1
31 }
32
33 names = make([]string, 0, size) // Empty with room to grow.
34 for n != 0 {
35 // Refill the buffer if necessary
36 if d.bufp >= d.nbuf {
37 d.bufp = 0
38 var errno error
39 d.nbuf, errno = syscall.ReadDirent(f.fd, d.buf)
40 if errno != nil {
41 return names, NewSyscallError("readdirent", errno)
42 }
43 if d.nbuf <= 0 {
44 break // EOF
45 }
46 }
47
48 // Drain the buffer
49 var nb, nc int
50 nb, nc, names = syscall.ParseDirent(d.buf[d.bufp:d.nbuf], n, names)
51 d.bufp += nb
52 n -= nc
53 }
54 if n >= 0 && len(names) == 0 {
55 return names, io.EOF
56 }
57 return names, nil
58 }