diff --git a/config/module/copy_dir.go b/config/module/copy_dir.go index 35ae3ed08..095f61d85 100644 --- a/config/module/copy_dir.go +++ b/config/module/copy_dir.go @@ -5,7 +5,6 @@ import ( "os" "path/filepath" "strings" - "syscall" ) // copyDir copies the src directory contents into dst. Both directories @@ -39,13 +38,7 @@ func copyDir(dst, src string) error { dstPath := filepath.Join(dst, path[len(src):]) // we don't want to try and copy the same file over itself. - if path == dstPath { - return nil - } - - // We still might have the same file through a link, so check the - // inode if we can - if eq, err := sameInode(path, dstPath); eq { + if eq, err := sameFile(path, dstPath); eq { return nil } else if err != nil { return err @@ -90,30 +83,27 @@ func copyDir(dst, src string) error { return filepath.Walk(src, walkFn) } -// sameInode looks up the inode for paths a and b and returns if they are -// equal. On windows this will always return false. -func sameInode(a, b string) (bool, error) { - var aIno, bIno uint64 - aStat, err := os.Stat(a) - if err != nil { - if os.IsNotExist(err) { - return false, nil - } - return false, err - } - if st, ok := aStat.Sys().(*syscall.Stat_t); ok { - aIno = st.Ino +// sameFile tried to determine if to paths are the same file. +// If the paths don't match, we lookup the inode on supported systems. +func sameFile(a, b string) (bool, error) { + if a == b { + return true, nil } - bStat, err := os.Stat(b) + aIno, err := inode(a) if err != nil { if os.IsNotExist(err) { return false, nil } return false, err } - if st, ok := bStat.Sys().(*syscall.Stat_t); ok { - bIno = st.Ino + + bIno, err := inode(b) + if err != nil { + if os.IsNotExist(err) { + return false, nil + } + return false, err } if aIno > 0 && aIno == bIno { diff --git a/config/module/inode.go b/config/module/inode.go new file mode 100644 index 000000000..a49e8a19d --- /dev/null +++ b/config/module/inode.go @@ -0,0 +1,21 @@ +// +build !windows + +package module + +import ( + "fmt" + "os" + "syscall" +) + +// lookup the inode of a file on posix systems +func inode(path string) (uint64, error) { + stat, err := os.Stat(path) + if err != nil { + return 0, err + } + if st, ok := stat.Sys().(*syscall.Stat_t); ok { + return st.Ino, nil + } + return 0, fmt.Errorf("could not determine file inode") +} diff --git a/config/module/inode_windows.go b/config/module/inode_windows.go new file mode 100644 index 000000000..3f5d5e7b1 --- /dev/null +++ b/config/module/inode_windows.go @@ -0,0 +1,6 @@ +package module + +// no syscall.Stat_t on windows, return 0 for inodes +func inode(path string) (uint64, error) { + return 0, nil +}