1// +build darwin dragonfly freebsd linux netbsd openbsd 2 3package godirwalk 4 5import ( 6 "os" 7 "path/filepath" 8 "syscall" 9) 10 11// modeType converts a syscall defined constant, which is in purview of OS, to a 12// constant defined by Go, assumed by this project to be stable. 13// 14// When the syscall constant is not recognized, this function falls back to a 15// Stat on the file system. 16func modeType(de *syscall.Dirent, osDirname, osChildname string) (os.FileMode, error) { 17 switch de.Type { 18 case syscall.DT_REG: 19 return 0, nil 20 case syscall.DT_DIR: 21 return os.ModeDir, nil 22 case syscall.DT_LNK: 23 return os.ModeSymlink, nil 24 case syscall.DT_CHR: 25 return os.ModeDevice | os.ModeCharDevice, nil 26 case syscall.DT_BLK: 27 return os.ModeDevice, nil 28 case syscall.DT_FIFO: 29 return os.ModeNamedPipe, nil 30 case syscall.DT_SOCK: 31 return os.ModeSocket, nil 32 default: 33 // If syscall returned unknown type (e.g., DT_UNKNOWN, DT_WHT), 34 // then resolve actual mode by getting stat. 35 fi, err := os.Lstat(filepath.Join(osDirname, osChildname)) 36 if err != nil { 37 return 0, err 38 } 39 // Even though the stat provided all file mode bits, we want to 40 // ensure same values returned to caller regardless of whether 41 // we obtained file mode bits from syscall or stat call. 42 // Therefore mask out the additional file mode bits that are 43 // provided by stat but not by the syscall, so users can rely on 44 // their values. 45 return fi.Mode() & os.ModeType, nil 46 } 47} 48