summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Unterwurzacher2015-09-04 09:05:52 +0200
committerJakob Unterwurzacher2015-09-04 09:05:52 +0200
commit779ad6dda3d7926c1f68e72600a5db3764e6039d (patch)
treeadfd3f094442c3e453716880bfe8b8e793836b4f
parent6a110b8dde07a4bfa967547be8bf5b3756511a8b (diff)
Properly handle FileMode
-rw-r--r--frontend/node.go36
1 files changed, 35 insertions, 1 deletions
diff --git a/frontend/node.go b/frontend/node.go
index 53ffb26..833be2e 100644
--- a/frontend/node.go
+++ b/frontend/node.go
@@ -22,6 +22,40 @@ type Node struct {
parentFS *FS
}
+// FileModeFromStat - create os.FileMode from stat value
+// For some reason, they use different constants.
+// Adapted from https://golang.org/src/os/stat_linux.go
+func FileModeFromStat(st *syscall.Stat_t) os.FileMode {
+ fileMode := os.FileMode(st.Mode & 0777)
+ switch st.Mode & syscall.S_IFMT {
+ case syscall.S_IFBLK:
+ fileMode |= os.ModeDevice
+ case syscall.S_IFCHR:
+ fileMode |= os.ModeDevice | os.ModeCharDevice
+ case syscall.S_IFDIR:
+ fileMode |= os.ModeDir
+ case syscall.S_IFIFO:
+ fileMode |= os.ModeNamedPipe
+ case syscall.S_IFLNK:
+ fileMode |= os.ModeSymlink
+ case syscall.S_IFREG:
+ // nothing to do
+ case syscall.S_IFSOCK:
+ fileMode |= os.ModeSocket
+ }
+ if st.Mode & syscall.S_ISGID != 0 {
+ fileMode |= os.ModeSetgid
+ }
+ if st.Mode & syscall.S_ISUID != 0 {
+ fileMode |= os.ModeSetuid
+ }
+ if st.Mode & syscall.S_ISVTX != 0 {
+ fileMode |= os.ModeSticky
+ }
+ return fileMode
+}
+
+
func StatToAttr(s *syscall.Stat_t, a *fuse.Attr) {
a.Inode = s.Ino
a.Size = uint64(s.Size)
@@ -29,7 +63,7 @@ func StatToAttr(s *syscall.Stat_t, a *fuse.Attr) {
a.Atime = time.Unix(s.Atim.Sec, s.Atim.Nsec)
a.Mtime = time.Unix(s.Mtim.Sec, s.Mtim.Nsec)
a.Ctime = time.Unix(s.Ctim.Sec, s.Ctim.Nsec)
- a.Mode = os.FileMode(s.Mode) | os.ModeDir
+ a.Mode = FileModeFromStat(s)
a.Nlink = uint32(s.Nlink)
a.Uid = uint32(s.Uid)
a.Gid = uint32(s.Gid)