aboutsummaryrefslogtreecommitdiff
path: root/internal/fusefrontend/node_dir_ops.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/fusefrontend/node_dir_ops.go')
-rw-r--r--internal/fusefrontend/node_dir_ops.go19
1 files changed, 19 insertions, 0 deletions
diff --git a/internal/fusefrontend/node_dir_ops.go b/internal/fusefrontend/node_dir_ops.go
index 97327ce..ba78ac0 100644
--- a/internal/fusefrontend/node_dir_ops.go
+++ b/internal/fusefrontend/node_dir_ops.go
@@ -6,8 +6,10 @@ import (
"io"
"runtime"
"syscall"
+ "unicode/utf8"
"golang.org/x/sys/unix"
+ "golang.org/x/text/unicode/norm"
"github.com/hanwen/go-fuse/v2/fs"
"github.com/hanwen/go-fuse/v2/fuse"
@@ -20,6 +22,22 @@ import (
const dsStoreName = ".DS_Store"
+// normalizeFilename converts filenames to NFC for consistent internal storage
+func normalizeFilename(name string) string {
+ if runtime.GOOS == "darwin" && utf8.ValidString(name) {
+ return norm.NFC.String(name)
+ }
+ return name
+}
+
+// normalizeFilenameForDisplay converts NFC to NFD for macOS GUI compatibility
+func normalizeFilenameForDisplay(name string) string {
+ if runtime.GOOS == "darwin" && utf8.ValidString(name) {
+ return norm.NFD.String(name)
+ }
+ return name
+}
+
// haveDsstore return true if one of the entries in "names" is ".DS_Store".
func haveDsstore(entries []fuse.DirEntry) bool {
for _, e := range entries {
@@ -70,6 +88,7 @@ func (n *Node) mkdirWithIv(dirfd int, cName string, mode uint32, context *fuse.C
//
// Symlink-safe through use of Mkdirat().
func (n *Node) Mkdir(ctx context.Context, name string, mode uint32, out *fuse.EntryOut) (*fs.Inode, syscall.Errno) {
+ name = normalizeFilename(name) // Always store as NFC
dirfd, cName, errno := n.prepareAtSyscall(name)
if errno != 0 {
return nil, errno