From 52763e19187bbbf43237eba95e950eeb5611672b Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Sun, 27 Jan 2019 19:14:55 +0000 Subject: [PATCH] local: when using `-l` fix setting modification times of symlinks #1152 Before this change it was setting the modification times of the things that the symlinks pointed to. Note that this is only implemented for unix style OSes. Other OSes will not attempt to set the modification time of a symlink. --- backend/local/lchtimes.go | 20 ++++++++++++++++++++ backend/local/lchtimes_unix.go | 28 ++++++++++++++++++++++++++++ backend/local/local.go | 7 ++++++- 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 backend/local/lchtimes.go create mode 100644 backend/local/lchtimes_unix.go diff --git a/backend/local/lchtimes.go b/backend/local/lchtimes.go new file mode 100644 index 000000000..2684beee5 --- /dev/null +++ b/backend/local/lchtimes.go @@ -0,0 +1,20 @@ +// +build windows plan9 + +package local + +import ( + "time" +) + +const haveLChtimes = false + +// lChtimes changes the access and modification times of the named +// link, similar to the Unix utime() or utimes() functions. +// +// The underlying filesystem may truncate or round the values to a +// less precise time unit. +// If there is an error, it will be of type *PathError. +func lChtimes(name string, atime time.Time, mtime time.Time) error { + // Does nothing + return nil +} diff --git a/backend/local/lchtimes_unix.go b/backend/local/lchtimes_unix.go new file mode 100644 index 000000000..c7f570eac --- /dev/null +++ b/backend/local/lchtimes_unix.go @@ -0,0 +1,28 @@ +// +build !windows,!plan9 + +package local + +import ( + "os" + "time" + + "golang.org/x/sys/unix" +) + +const haveLChtimes = true + +// lChtimes changes the access and modification times of the named +// link, similar to the Unix utime() or utimes() functions. +// +// The underlying filesystem may truncate or round the values to a +// less precise time unit. +// If there is an error, it will be of type *PathError. +func lChtimes(name string, atime time.Time, mtime time.Time) error { + var utimes [2]unix.Timespec + utimes[0] = unix.NsecToTimespec(atime.UnixNano()) + utimes[1] = unix.NsecToTimespec(mtime.UnixNano()) + if e := unix.UtimesNanoAt(unix.AT_FDCWD, name, utimes[0:], unix.AT_SYMLINK_NOFOLLOW); e != nil { + return &os.PathError{Op: "lchtimes", Path: name, Err: e} + } + return nil +} diff --git a/backend/local/local.go b/backend/local/local.go index 8beb48b77..a17a0cf53 100644 --- a/backend/local/local.go +++ b/backend/local/local.go @@ -744,7 +744,12 @@ func (o *Object) ModTime() time.Time { // SetModTime sets the modification time of the local fs object func (o *Object) SetModTime(modTime time.Time) error { - err := os.Chtimes(o.path, modTime, modTime) + var err error + if o.translatedLink { + err = lChtimes(o.path, modTime, modTime) + } else { + err = os.Chtimes(o.path, modTime, modTime) + } if err != nil { return err }