diff --git a/hack/make.sh b/hack/make.sh index 4db4349518..f3264c9ce3 100755 --- a/hack/make.sh +++ b/hack/make.sh @@ -107,6 +107,16 @@ LDFLAGS_STATIC_DOCKER=" -extldflags \"$EXTLDFLAGS_STATIC_DOCKER\" " +if [ "$(uname -s)" = 'FreeBSD' ]; then + # Tell cgo the compiler is Clang, not GCC + # https://code.google.com/p/go/source/browse/src/cmd/cgo/gcc.go?spec=svne77e74371f2340ee08622ce602e9f7b15f29d8d3&r=e6794866ebeba2bf8818b9261b54e2eef1c9e588#752 + export CC=clang + + # "-extld clang" is a workaround for + # https://code.google.com/p/go/issues/detail?id=6845 + LDFLAGS="$LDFLAGS -extld clang" +fi + HAVE_GO_TEST_COVER= if \ go help testflag | grep -- -cover > /dev/null \ @@ -142,7 +152,7 @@ go_test_dir() { # holding certain files ($1 parameter), and prints their paths on standard # output, one per line. find_dirs() { - find -not \( \ + find . -not \( \ \( \ -wholename './vendor' \ -o -wholename './integration' \ diff --git a/pkg/system/utimes_freebsd.go b/pkg/system/utimes_freebsd.go new file mode 100644 index 0000000000..ceaa044c1c --- /dev/null +++ b/pkg/system/utimes_freebsd.go @@ -0,0 +1,24 @@ +package system + +import ( + "syscall" + "unsafe" +) + +func LUtimesNano(path string, ts []syscall.Timespec) error { + var _path *byte + _path, err := syscall.BytePtrFromString(path) + if err != nil { + return err + } + + if _, _, err := syscall.Syscall(syscall.SYS_LUTIMES, uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), 0); err != 0 && err != syscall.ENOSYS { + return err + } + + return nil +} + +func UtimesNano(path string, ts []syscall.Timespec) error { + return syscall.UtimesNano(path, ts) +} diff --git a/pkg/system/utimes_test.go b/pkg/system/utimes_test.go new file mode 100644 index 0000000000..38e4020cb5 --- /dev/null +++ b/pkg/system/utimes_test.go @@ -0,0 +1,64 @@ +package system + +import ( + "io/ioutil" + "os" + "path/filepath" + "syscall" + "testing" +) + +func prepareFiles(t *testing.T) (string, string, string) { + dir, err := ioutil.TempDir("", "docker-system-test") + if err != nil { + t.Fatal(err) + } + + file := filepath.Join(dir, "exist") + if err := ioutil.WriteFile(file, []byte("hello"), 0644); err != nil { + t.Fatal(err) + } + + invalid := filepath.Join(dir, "doesnt-exist") + + symlink := filepath.Join(dir, "symlink") + if err := os.Symlink(file, symlink); err != nil { + t.Fatal(err) + } + + return file, invalid, symlink +} + +func TestLUtimesNano(t *testing.T) { + file, invalid, symlink := prepareFiles(t) + + before, err := os.Stat(file) + if err != nil { + t.Fatal(err) + } + + ts := []syscall.Timespec{{0, 0}, {0, 0}} + if err := LUtimesNano(symlink, ts); err != nil { + t.Fatal(err) + } + + symlinkInfo, err := os.Lstat(symlink) + if err != nil { + t.Fatal(err) + } + if before.ModTime().Unix() == symlinkInfo.ModTime().Unix() { + t.Fatal("The modification time of the symlink should be different") + } + + fileInfo, err := os.Stat(file) + if err != nil { + t.Fatal(err) + } + if before.ModTime().Unix() != fileInfo.ModTime().Unix() { + t.Fatal("The modification time of the file should be same") + } + + if err := LUtimesNano(invalid, ts); err == nil { + t.Fatal("Doesn't return an error on a non-existing file") + } +} diff --git a/pkg/system/utimes_unsupported.go b/pkg/system/utimes_unsupported.go index d247ba283e..9a8cf9cd4a 100644 --- a/pkg/system/utimes_unsupported.go +++ b/pkg/system/utimes_unsupported.go @@ -1,4 +1,4 @@ -// +build !linux +// +build !linux,!freebsd package system