mirror of
https://github.com/restic/restic.git
synced 2026-02-23 09:16:24 +00:00
node/Linux: Implement setting timestamps for symlinks
This commit is contained in:
@@ -2,8 +2,10 @@ package restic
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func (node *Node) OpenForReading() (*os.File, error) {
|
||||
@@ -22,3 +24,36 @@ func (node *Node) fillTimes(stat *syscall.Stat_t) {
|
||||
func changeTime(stat *syscall.Stat_t) time.Time {
|
||||
return time.Unix(stat.Ctim.Unix())
|
||||
}
|
||||
|
||||
func (node Node) restoreSymlinkTimestamps(path string, utimes [2]syscall.Timespec) error {
|
||||
dir, err := os.Open(filepath.Dir(path))
|
||||
defer dir.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return utimesNanoAt(int(dir.Fd()), filepath.Base(path), utimes, AT_SYMLINK_NOFOLLOW)
|
||||
}
|
||||
|
||||
// very lowlevel below
|
||||
|
||||
const AT_SYMLINK_NOFOLLOW = 0x100
|
||||
|
||||
func utimensat(dirfd int, path string, times *[2]syscall.Timespec, flags int) (err error) {
|
||||
var _p0 *byte
|
||||
_p0, err = syscall.BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_, _, e1 := syscall.Syscall6(syscall.SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
|
||||
if e1 != 0 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error)
|
||||
|
||||
func utimesNanoAt(dirfd int, path string, ts [2]syscall.Timespec, flags int) (err error) {
|
||||
return utimensat(dirfd, path, (*[2]syscall.Timespec)(unsafe.Pointer(&ts[0])), flags)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user