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 }