File: dirent.go

package info (click to toggle)
golang-github-charlievieth-fastwalk 1.0.14-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 372 kB
  • sloc: makefile: 80; sh: 35; asm: 13
file content (73 lines) | stat: -rw-r--r-- 1,970 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package fastwalk

import (
	"io/fs"
	"os"
	"sync"
	"sync/atomic"
	"syscall"
	"unsafe"
)

type fileInfo struct {
	once sync.Once
	fs.FileInfo
	err error
}

func loadFileInfo(pinfo **fileInfo) *fileInfo {
	ptr := (*unsafe.Pointer)(unsafe.Pointer(pinfo))
	fi := (*fileInfo)(atomic.LoadPointer(ptr))
	if fi == nil {
		fi = &fileInfo{}
		if !atomic.CompareAndSwapPointer(
			(*unsafe.Pointer)(unsafe.Pointer(pinfo)), // adrr
			nil,                                      // old
			unsafe.Pointer(fi),                       // new
		) {
			fi = (*fileInfo)(atomic.LoadPointer(ptr))
		}
	}
	return fi
}

// StatDirEntry returns a [fs.FileInfo] describing the named file ([os.Stat]).
// If de is a [fastwalk.DirEntry] its Stat method is used and the returned
// FileInfo may be cached from a prior call to Stat. If a cached result is not
// desired, users should just call [os.Stat] directly.
//
// This is a helper function for calling Stat on the DirEntry passed to the
// walkFn argument to [Walk].
//
// The path argument is only used if de is not of type [fastwalk.DirEntry].
// Therefore, de should be the DirEntry describing path.
func StatDirEntry(path string, de fs.DirEntry) (fs.FileInfo, error) {
	if de == nil {
		return nil, &os.PathError{Op: "stat", Path: path, Err: syscall.EINVAL}
	}
	if de.Type()&os.ModeSymlink == 0 {
		return de.Info()
	}
	if d, ok := de.(DirEntry); ok {
		return d.Stat()
	}
	return os.Stat(path)
}

// DirEntryDepth returns the depth at which entry de was generated relative
// to the root being walked or -1 if de does not have type [fastwalk.DirEntry].
//
// This is a helper function that saves the user from having to cast the
// [fs.DirEntry] argument to their walk function to a [fastwalk.DirEntry]
// and is equivalent to the below code:
//
//	if d, _ := de.(DirEntry); d != nil {
//		return d.Depth()
//	}
//	return -1
func DirEntryDepth(de fs.DirEntry) int {
	if d, _ := de.(DirEntry); d != nil {
		return d.Depth()
	}
	return -1
}