diff --git a/pkg/util/mount/mount.go b/pkg/util/mount/mount.go index f30db7692e..cbc083dac0 100644 --- a/pkg/util/mount/mount.go +++ b/pkg/util/mount/mount.go @@ -19,6 +19,7 @@ limitations under the License. package mount import ( + "fmt" "os" "path/filepath" "strings" @@ -337,3 +338,37 @@ func startsWithBackstep(rel string) bool { // normalize to / and check for ../ return rel == ".." || strings.HasPrefix(filepath.ToSlash(rel), "../") } + +// getFileType checks for file/directory/socket and block/character devices +func getFileType(pathname string) (FileType, error) { + var pathType FileType + info, err := os.Stat(pathname) + if os.IsNotExist(err) { + return pathType, fmt.Errorf("path %q does not exist", pathname) + } + // err in call to os.Stat + if err != nil { + return pathType, err + } + + // checks whether the mode is the target mode + isSpecificMode := func(mode, targetMode os.FileMode) bool { + return mode&targetMode == targetMode + } + + mode := info.Mode() + if mode.IsDir() { + return FileTypeDirectory, nil + } else if mode.IsRegular() { + return FileTypeFile, nil + } else if isSpecificMode(mode, os.ModeSocket) { + return FileTypeSocket, nil + } else if isSpecificMode(mode, os.ModeDevice) { + if isSpecificMode(mode, os.ModeCharDevice) { + return FileTypeCharDev, nil + } + return FileTypeBlockDev, nil + } + + return pathType, fmt.Errorf("only recognise file, directory, socket, block device and character device") +} diff --git a/pkg/util/mount/mount_linux.go b/pkg/util/mount/mount_linux.go index 012b32673f..2eac05a7cc 100644 --- a/pkg/util/mount/mount_linux.go +++ b/pkg/util/mount/mount_linux.go @@ -423,31 +423,7 @@ func (mounter *Mounter) MakeRShared(path string) error { } func (mounter *Mounter) GetFileType(pathname string) (FileType, error) { - var pathType FileType - finfo, err := os.Stat(pathname) - if os.IsNotExist(err) { - return pathType, fmt.Errorf("path %q does not exist", pathname) - } - // err in call to os.Stat - if err != nil { - return pathType, err - } - - mode := finfo.Sys().(*syscall.Stat_t).Mode - switch mode & syscall.S_IFMT { - case syscall.S_IFSOCK: - return FileTypeSocket, nil - case syscall.S_IFBLK: - return FileTypeBlockDev, nil - case syscall.S_IFCHR: - return FileTypeCharDev, nil - case syscall.S_IFDIR: - return FileTypeDirectory, nil - case syscall.S_IFREG: - return FileTypeFile, nil - } - - return pathType, fmt.Errorf("only recognise file, directory, socket, block device and character device") + return getFileType(pathname) } func (mounter *Mounter) MakeDir(pathname string) error { diff --git a/pkg/util/mount/mount_windows.go b/pkg/util/mount/mount_windows.go index 12e1bca118..0384ba179f 100644 --- a/pkg/util/mount/mount_windows.go +++ b/pkg/util/mount/mount_windows.go @@ -201,31 +201,7 @@ func (mounter *Mounter) MakeRShared(path string) error { // GetFileType checks for sockets/block/character devices func (mounter *Mounter) GetFileType(pathname string) (FileType, error) { - var pathType FileType - info, err := os.Stat(pathname) - if os.IsNotExist(err) { - return pathType, fmt.Errorf("path %q does not exist", pathname) - } - // err in call to os.Stat - if err != nil { - return pathType, err - } - - mode := info.Sys().(*syscall.Win32FileAttributeData).FileAttributes - switch mode & syscall.S_IFMT { - case syscall.S_IFSOCK: - return FileTypeSocket, nil - case syscall.S_IFBLK: - return FileTypeBlockDev, nil - case syscall.S_IFCHR: - return FileTypeCharDev, nil - case syscall.S_IFDIR: - return FileTypeDirectory, nil - case syscall.S_IFREG: - return FileTypeFile, nil - } - - return pathType, fmt.Errorf("only recognise file, directory, socket, block device and character device") + return getFileType(pathname) } // MakeFile creates a new directory