*: 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 <tklauser@distanz.ch>
This commit is contained in:
Tobias Klauser 2017-10-20 11:39:11 +02:00
parent 7742183cd4
commit 3fe21921b5
4 changed files with 33 additions and 42 deletions

22
lchtimes_unix.go Normal file
View file

@ -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
}

11
lchtimes_unsupported.go Normal file
View file

@ -0,0 +1,11 @@
// +build windows
package mtree
import (
"time"
)
func lchtimes(name string, atime time.Time, mtime time.Time) error {
return nil
}

View file

@ -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
}

View file

@ -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
}