dir_unix.go 1.2 KB

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