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 dragonfly freebsd linux nacl netbsd openbsd solaris 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 = fixCount(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 } 59