diff options
Diffstat (limited to 'src/pkg/os/stat_darwin.go')
-rw-r--r-- | src/pkg/os/stat_darwin.go | 71 |
1 files changed, 50 insertions, 21 deletions
diff --git a/src/pkg/os/stat_darwin.go b/src/pkg/os/stat_darwin.go index 0661a6d59..e1f93fac3 100644 --- a/src/pkg/os/stat_darwin.go +++ b/src/pkg/os/stat_darwin.go @@ -4,29 +4,58 @@ package os -import "syscall" +import ( + "syscall" + "time" +) -func isSymlink(stat *syscall.Stat_t) bool { - return stat.Mode&syscall.S_IFMT == syscall.S_IFLNK +func sameFile(fs1, fs2 *FileStat) bool { + sys1 := fs1.Sys.(*syscall.Stat_t) + sys2 := fs2.Sys.(*syscall.Stat_t) + return sys1.Dev == sys2.Dev && sys1.Ino == sys2.Ino } -func fileInfoFromStat(name string, fi *FileInfo, lstat, stat *syscall.Stat_t) *FileInfo { - fi.Dev = uint64(stat.Dev) - fi.Ino = stat.Ino - fi.Nlink = uint64(stat.Nlink) - fi.Mode = uint32(stat.Mode) - fi.Uid = int(stat.Uid) - fi.Gid = int(stat.Gid) - fi.Rdev = uint64(stat.Rdev) - fi.Size = stat.Size - fi.Blksize = int64(stat.Blksize) - fi.Blocks = stat.Blocks - fi.Atime_ns = syscall.TimespecToNsec(stat.Atimespec) - fi.Mtime_ns = syscall.TimespecToNsec(stat.Mtimespec) - fi.Ctime_ns = syscall.TimespecToNsec(stat.Ctimespec) - fi.Name = basename(name) - if isSymlink(lstat) && !isSymlink(stat) { - fi.FollowedSymlink = true +func fileInfoFromStat(st *syscall.Stat_t, name string) FileInfo { + fs := &FileStat{ + name: basename(name), + size: int64(st.Size), + modTime: timespecToTime(st.Mtimespec), + Sys: st, } - return fi + fs.mode = FileMode(st.Mode & 0777) + switch st.Mode & syscall.S_IFMT { + case syscall.S_IFBLK, syscall.S_IFWHT: + fs.mode |= ModeDevice + case syscall.S_IFCHR: + fs.mode |= ModeDevice | ModeCharDevice + case syscall.S_IFDIR: + fs.mode |= ModeDir + case syscall.S_IFIFO: + fs.mode |= ModeNamedPipe + case syscall.S_IFLNK: + fs.mode |= ModeSymlink + case syscall.S_IFREG: + // nothing to do + case syscall.S_IFSOCK: + fs.mode |= ModeSocket + } + if st.Mode&syscall.S_ISGID != 0 { + fs.mode |= ModeSetgid + } + if st.Mode&syscall.S_ISUID != 0 { + fs.mode |= ModeSetuid + } + if st.Mode&syscall.S_ISVTX != 0 { + fs.mode |= ModeSticky + } + return fs +} + +func timespecToTime(ts syscall.Timespec) time.Time { + return time.Unix(int64(ts.Sec), int64(ts.Nsec)) +} + +// For testing. +func atime(fi FileInfo) time.Time { + return timespecToTime(fi.(*FileStat).Sys.(*syscall.Stat_t).Atimespec) } |