diff --git a/archive/changes_test.go b/archive/changes_test.go index f4316ce..00bd69f 100644 --- a/archive/changes_test.go +++ b/archive/changes_test.go @@ -8,6 +8,8 @@ import ( "sort" "testing" "time" + + "github.com/docker/docker/pkg/system" ) func max(x, y int) int { @@ -87,7 +89,7 @@ func createSampleDir(t *testing.T, root string) { if info.filetype != Symlink { // Set a consistent ctime, atime for all files and dirs - if err := os.Chtimes(p, now, now); err != nil { + if err := system.Chtimes(p, now, now); err != nil { t.Fatal(err) } } @@ -289,7 +291,7 @@ func mutateSampleDir(t *testing.T, root string) { } // Touch file - if err := os.Chtimes(path.Join(root, "file4"), time.Now().Add(time.Second), time.Now().Add(time.Second)); err != nil { + if err := system.Chtimes(path.Join(root, "file4"), time.Now().Add(time.Second), time.Now().Add(time.Second)); err != nil { t.Fatal(err) } @@ -333,7 +335,7 @@ func mutateSampleDir(t *testing.T, root string) { } // Touch dir - if err := os.Chtimes(path.Join(root, "dir3"), time.Now().Add(time.Second), time.Now().Add(time.Second)); err != nil { + if err := system.Chtimes(path.Join(root, "dir3"), time.Now().Add(time.Second), time.Now().Add(time.Second)); err != nil { t.Fatal(err) } } diff --git a/system/chtimes.go b/system/chtimes.go index acf3f56..7637f12 100644 --- a/system/chtimes.go +++ b/system/chtimes.go @@ -43,5 +43,10 @@ func Chtimes(name string, atime time.Time, mtime time.Time) error { return err } + // Take platform specific action for setting create time. + if err := setCTime(name, mtime); err != nil { + return err + } + return nil } diff --git a/system/chtimes_unix.go b/system/chtimes_unix.go new file mode 100644 index 0000000..09d58bc --- /dev/null +++ b/system/chtimes_unix.go @@ -0,0 +1,14 @@ +// +build !windows + +package system + +import ( + "time" +) + +//setCTime will set the create time on a file. On Unix, the create +//time is updated as a side effect of setting the modified time, so +//no action is required. +func setCTime(path string, ctime time.Time) error { + return nil +} diff --git a/system/chtimes_unix_test.go b/system/chtimes_unix_test.go index fcd5940..0aafe1d 100644 --- a/system/chtimes_unix_test.go +++ b/system/chtimes_unix_test.go @@ -1,4 +1,4 @@ -// +build linux freebsd +// +build !windows package system diff --git a/system/chtimes_windows.go b/system/chtimes_windows.go new file mode 100644 index 0000000..2945868 --- /dev/null +++ b/system/chtimes_windows.go @@ -0,0 +1,27 @@ +// +build windows + +package system + +import ( + "syscall" + "time" +) + +//setCTime will set the create time on a file. On Windows, this requires +//calling SetFileTime and explicitly including the create time. +func setCTime(path string, ctime time.Time) error { + ctimespec := syscall.NsecToTimespec(ctime.UnixNano()) + pathp, e := syscall.UTF16PtrFromString(path) + if e != nil { + return e + } + h, e := syscall.CreateFile(pathp, + syscall.FILE_WRITE_ATTRIBUTES, syscall.FILE_SHARE_WRITE, nil, + syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0) + if e != nil { + return e + } + defer syscall.Close(h) + c := syscall.NsecToFiletime(syscall.TimespecToNsec(ctimespec)) + return syscall.SetFileTime(h, &c, nil, nil) +}