diff --git a/pkg/file/stat.go b/pkg/file/stat.go index a23c32f..f5d5067 100644 --- a/pkg/file/stat.go +++ b/pkg/file/stat.go @@ -2,6 +2,7 @@ package file import ( "errors" + "io/fs" "os" ) @@ -25,12 +26,7 @@ func Exists(path string) (bool, error) { // // It returns false on any error, e.g. if the file does not exist or on insufficient permissions func IsDir(path string) bool { - fileInfo, err := os.Stat(path) - if os.IsNotExist(err) { - return false - } - - return fileInfo.IsDir() + return isFileMode(path, os.ModeDir) } // IsRegular returns true if the given path is a regular file @@ -38,12 +34,10 @@ func IsDir(path string) bool { // It resolves all symbolic links // It returns false on any error, e.g. if the file does not exist or on insufficient permissions func IsRegular(path string) bool { - fileInfo, err := os.Stat(path) - if os.IsNotExist(err) { - return false + if s, err := os.Stat(path); err == nil { + return s.Mode().IsRegular() } - - return fileInfo.Mode().IsRegular() + return false } // IsSymlink returns true if the given path is a symlink @@ -51,12 +45,7 @@ func IsRegular(path string) bool { // It does not resolve any symbolic links // It returns false on any error, e.g. if the file does not exist or on insufficient permissions func IsSymlink(path string) bool { - fileInfo, err := os.Lstat(path) - if os.IsNotExist(err) { - return false - } - - return fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink + return isFileModeL(path, os.ModeSymlink) } // IsNamedPipe returns true if the given path is a named pipe @@ -77,12 +66,7 @@ func IsNamedPipe(path string) bool { // It resolves all symbolic links // It returns false on any error, e.g. if the file does not exist or on insufficient permissions func IsSocket(path string) bool { - fileInfo, err := os.Stat(path) - if os.IsNotExist(err) { - return false - } - - return fileInfo.Mode()&os.ModeSocket == os.ModeSocket + return isFileMode(path, os.ModeSocket) } // IsDevice returns true if the given path is a device @@ -90,22 +74,36 @@ func IsSocket(path string) bool { // It resolves all symbolic links // It returns false on any error, e.g. if the file does not exist or on insufficient permissions func IsDevice(path string) bool { - fileInfo, err := os.Stat(path) - if os.IsNotExist(err) { - return false - } - - return fileInfo.Mode()&os.ModeDevice == os.ModeDevice + return isFileMode(path, os.ModeDevice) } // IsFile returns true if the given path is a regular file, symlink, socket, or device // // It returns false on any error, e.g. if the file does not exist or on insufficient permissions func IsFile(path string) bool { - exists, err := Exists(path) - if err != nil { - return false + return IsRegular(path) || + IsSymlink(path) || + IsNamedPipe(path) || + IsSocket(path) || + IsDevice(path) +} + +// isFileMode returns true if the given path has the given file mode, resolving any symbolic links +// +// It returns false on any error, e.g. if the file does not exist or on insufficient permissions +func isFileMode(path string, fileMode fs.FileMode) bool { + if s, err := os.Stat(path); err == nil { + return s.Mode()&fileMode != 0 } + return false +} - return exists && !IsDir(path) +// isFileModeL returns true if the given path has the given file mode, not resolving any symbolic links +// +// It returns false on any error, e.g. if the file does not exist or on insufficient permissions +func isFileModeL(path string, fileMode fs.FileMode) bool { + if s, err := os.Lstat(path); err == nil { + return s.Mode()&fileMode != 0 + } + return false }