Home | History | Annotate | Download | only in os
      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