mirror of
https://github.com/restic/restic.git
synced 2025-12-11 18:47:50 +00:00
fs: Refactor UtimesNano replacements
Previously, nodeRestoreTimestamps would do something like
if node.Type == restic.NodeTypeSymlink {
return nodeRestoreSymlinkTimestamps(...)
}
return syscall.UtimesNano(...)
where nodeRestoreSymlinkTimestamps was either a no-op or a
reimplementation of syscall.UtimesNano that handles symlinks, with some
repeated converting between timestamp types. The Linux implementation
was a bit clumsy, requiring three syscalls to set the timestamps.
In this new setup, there is a function utimesNano that has three
implementations:
* on Linux, it's a modified syscall.UtimesNano that uses
AT_SYMLINK_NOFOLLOW and AT_FDCWD so it can handle any type in a single
call;
* on other Unix platforms, it just calls the syscall function after
skipping symlinks;
* on Windows, it's the modified UtimesNano that was previously called
nodeRestoreSymlinkTimestamps, except with different arguments.
This commit is contained in:
@@ -1,18 +1,15 @@
|
||||
package fs
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
"github.com/restic/restic/internal/errors"
|
||||
"github.com/restic/restic/internal/restic"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func nodeRestoreSymlinkTimestamps(path string, utimes [2]syscall.Timespec) error {
|
||||
// utimesNano is like syscall.UtimesNano, except that it does not follow symlinks.
|
||||
func utimesNano(path string, atime, mtime int64, _ restic.NodeType) error {
|
||||
times := []unix.Timespec{
|
||||
{Sec: utimes[0].Sec, Nsec: utimes[0].Nsec},
|
||||
{Sec: utimes[1].Sec, Nsec: utimes[1].Nsec},
|
||||
unix.NsecToTimespec(atime),
|
||||
unix.NsecToTimespec(mtime),
|
||||
}
|
||||
|
||||
err := unix.UtimesNanoAt(unix.AT_FDCWD, path, times, unix.AT_SYMLINK_NOFOLLOW)
|
||||
return errors.Wrap(err, "UtimesNanoAt")
|
||||
return unix.UtimesNanoAt(unix.AT_FDCWD, path, times, unix.AT_SYMLINK_NOFOLLOW)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user