1//go:build !darwin && !(aix || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris)
2
3package fastwalk
4
5import "os"
6
7// readDir calls fn for each directory entry in dirName.
8// It does not descend into directories or follow symlinks.
9// If fn returns a non-nil error, readDir returns with that error
10// immediately.
11func (w *walker) readDir(dirName string, depth int) error {
12 f, err := os.Open(dirName)
13 if err != nil {
14 return err
15 }
16 des, readErr := f.ReadDir(-1)
17 f.Close()
18 if readErr != nil && len(des) == 0 {
19 return readErr
20 }
21
22 var p *[]DirEntry
23 if w.sortMode != SortNone {
24 p = direntSlicePool.Get().(*[]DirEntry)
25 }
26 defer putDirentSlice(p)
27
28 var skipFiles bool
29 for _, d := range des {
30 if skipFiles && d.Type().IsRegular() {
31 continue
32 }
33 // Need to use FileMode.Type().Type() for fs.DirEntry
34 e := newDirEntry(dirName, d, depth)
35 if w.sortMode == SortNone {
36 if err := w.onDirEnt(dirName, d.Name(), e); err != nil {
37 if err != ErrSkipFiles {
38 return err
39 }
40 skipFiles = true
41 }
42 } else {
43 *p = append(*p, e)
44 }
45 }
46 if w.sortMode == SortNone {
47 return readErr
48 }
49
50 dents := *p
51 sortDirents(w.sortMode, dents)
52 for _, d := range dents {
53 d := d
54 if skipFiles && d.Type().IsRegular() {
55 continue
56 }
57 if err := w.onDirEnt(dirName, d.Name(), d); err != nil {
58 if err != ErrSkipFiles {
59 return err
60 }
61 skipFiles = true
62 }
63 }
64 return readErr
65}