Add proper build constraints for GH-7273

The syscall.Stat_t type doesn't exist on windows, so the inode lookup
needs to be in a file with proper build constraints.
This commit is contained in:
James Bardin 2016-06-23 08:02:32 -04:00
parent d39760e620
commit 525485c213
3 changed files with 41 additions and 24 deletions

View File

@ -5,7 +5,6 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"syscall"
) )
// copyDir copies the src directory contents into dst. Both directories // 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):]) dstPath := filepath.Join(dst, path[len(src):])
// we don't want to try and copy the same file over itself. // we don't want to try and copy the same file over itself.
if path == dstPath { if eq, err := sameFile(path, dstPath); eq {
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 {
return nil return nil
} else if err != nil { } else if err != nil {
return err return err
@ -90,30 +83,27 @@ func copyDir(dst, src string) error {
return filepath.Walk(src, walkFn) return filepath.Walk(src, walkFn)
} }
// sameInode looks up the inode for paths a and b and returns if they are // sameFile tried to determine if to paths are the same file.
// equal. On windows this will always return false. // If the paths don't match, we lookup the inode on supported systems.
func sameInode(a, b string) (bool, error) { func sameFile(a, b string) (bool, error) {
var aIno, bIno uint64 if a == b {
aStat, err := os.Stat(a) return true, nil
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
} }
bStat, err := os.Stat(b) aIno, err := inode(a)
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return false, nil return false, nil
} }
return false, err 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 { if aIno > 0 && aIno == bIno {

21
config/module/inode.go Normal file
View File

@ -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")
}

View File

@ -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
}