返回 DeepSeek-Reasonix
darwin_identity.go
根目录 / internal / pathidentity / darwin_identity.go
1 package pathidentity
2
3 import (
4 "errors"
5 "strings"
6 "syscall"
7
8 "golang.org/x/text/unicode/norm"
9 )
10
11 // darwinVolume answers the two questions the darwin identity key asks of the
12 // volume holding a directory. It is platform-neutral so the rules are testable
13 // on every host; key_darwin.go binds it to statfs(2) and pathconf(2).
14 type darwinVolume struct {
15 fsType func(dir string) (string, error)
16 caseSensitive func(dir string) (int, error)
17 }
18
19 func darwinIdentityKeyBy(path, parent string, volume darwinVolume) (string, error) {
20 // A volume whose type cannot be read is not known to normalize names, so
21 // the path is kept as spelled rather than failing the whole lookup.
22 if fsType, err := volume.fsType(parent); err == nil && (fsType == "apfs" || fsType == "hfs") {
23 path = norm.NFD.String(path)
24 }
25 caseSensitive, err := volume.caseSensitive(parent)
26 if err != nil {
27 // FUSE volumes (sshfs over macFUSE) do not implement
28 // _PC_CASE_SENSITIVE; an undeclared answer keeps names distinct.
29 if !pathconfUndeclared(err) {
30 return "", err
31 }
32 caseSensitive = 1
33 }
34 if caseSensitive == 0 {
35 path = strings.ToLower(path)
36 }
37 return path, nil
38 }
39
40 func pathconfUndeclared(err error) bool {
41 return errors.Is(err, syscall.EINVAL) || errors.Is(err, syscall.ENOTSUP) || errors.Is(err, syscall.EOPNOTSUPP)
42 }
43
43 lines GO