From 3fe21921b5f276b0e319d31b4881d1d74eb7723b Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 20 Oct 2017 11:39:11 +0200 Subject: [PATCH] *: use UtimesNanoAt from x/sys/unix Use UtimesNanoAt from golang.org/x/sys/unix instead of manually crafting the syscall. Since UtimesNanoAt is provided for all unix-like OSes, factor out lchtimes to its own file with appropriate build tags. This allows to make use of it on darwin, dragonfly, freebsd, openbsd, netbsd and solaris in addition to linux. Signed-off-by: Tobias Klauser --- lchtimes_unix.go | 22 ++++++++++++++++++++++ lchtimes_unsupported.go | 11 +++++++++++ updatefuncs_linux.go | 37 ------------------------------------- updatefuncs_unsupported.go | 5 ----- 4 files changed, 33 insertions(+), 42 deletions(-) create mode 100644 lchtimes_unix.go create mode 100644 lchtimes_unsupported.go diff --git a/lchtimes_unix.go b/lchtimes_unix.go new file mode 100644 index 0000000..7cb5300 --- /dev/null +++ b/lchtimes_unix.go @@ -0,0 +1,22 @@ +// +build darwin dragonfly freebsd openbsd linux netbsd solaris + +package mtree + +import ( + "os" + "time" + + "golang.org/x/sys/unix" +) + +func lchtimes(name string, atime time.Time, mtime time.Time) error { + utimes := []unix.Timespec{ + unix.NsecToTimespec(atime.UnixNano()), + unix.NsecToTimespec(mtime.UnixNano()), + } + if e := unix.UtimesNanoAt(unix.AT_FDCWD, name, utimes, unix.AT_SYMLINK_NOFOLLOW); e != nil { + return &os.PathError{Op: "chtimes", Path: name, Err: e} + } + return nil + +} diff --git a/lchtimes_unsupported.go b/lchtimes_unsupported.go new file mode 100644 index 0000000..fac0532 --- /dev/null +++ b/lchtimes_unsupported.go @@ -0,0 +1,11 @@ +// +build windows + +package mtree + +import ( + "time" +) + +func lchtimes(name string, atime time.Time, mtime time.Time) error { + return nil +} diff --git a/updatefuncs_linux.go b/updatefuncs_linux.go index 4950c0f..b7d7e83 100644 --- a/updatefuncs_linux.go +++ b/updatefuncs_linux.go @@ -5,9 +5,6 @@ package mtree import ( "encoding/base64" "os" - "syscall" - "time" - "unsafe" "github.com/vbatts/go-mtree/xattr" ) @@ -22,37 +19,3 @@ func xattrUpdateKeywordFunc(path string, kv KeyVal) (os.FileInfo, error) { } return os.Lstat(path) } - -func lchtimes(name string, atime time.Time, mtime time.Time) error { - var utimes [2]syscall.Timespec - utimes[0] = syscall.NsecToTimespec(atime.UnixNano()) - utimes[1] = syscall.NsecToTimespec(mtime.UnixNano()) - if e := utimensat(atFdCwd, name, (*[2]syscall.Timespec)(unsafe.Pointer(&utimes[0])), atSymlinkNofollow); e != nil { - return &os.PathError{Op: "chtimes", Path: name, Err: e} - } - return nil - -} - -// from uapi/linux/fcntl.h -// don't follow symlinks -const atSymlinkNofollow = 0x100 - -// special value for utimes as the FD for the current working directory -const atFdCwd = -0x64 - -func utimensat(dirfd int, path string, times *[2]syscall.Timespec, flags int) (err error) { - if len(times) != 2 { - return syscall.EINVAL - } - 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 = syscall.Errno(e1) - } - return -} diff --git a/updatefuncs_unsupported.go b/updatefuncs_unsupported.go index a554964..9fc70e4 100644 --- a/updatefuncs_unsupported.go +++ b/updatefuncs_unsupported.go @@ -4,13 +4,8 @@ package mtree import ( "os" - "time" ) func xattrUpdateKeywordFunc(path string, kv KeyVal) (os.FileInfo, error) { return os.Lstat(path) } - -func lchtimes(name string, atime time.Time, mtime time.Time) error { - return nil -}