fastwalk_portable.go

 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}