From 7a56174f0086b32866ebd746a794417edbc678a1 Mon Sep 17 00:00:00 2001 From: Riku Voipio Date: Wed, 2 Mar 2016 21:58:15 +0200 Subject: [PATCH] x/sys/unix: fix time/utime/utimes on arm64 In commit "7e44b69 x/sys/unix: fix invalid syscall on linux/arm" a test was added for time/utime syscall. This test exposed that neither time/utime work on arm64, because they call the legacy syscall "utimes". As a new architecture, arm64 doesn't implement any legacy syscalls. Implement by first calling utimensat, using UtimesNano as exampple. Change-Id: Iffed410730c06ac4c8184241d16eebf08c367524 Reviewed-on: https://go-review.googlesource.com/20174 Reviewed-by: Brad Fitzpatrick Run-TryBot: Brad Fitzpatrick --- unix/syscall_linux.go | 13 ++++++++++++- unix/syscall_linux_arm64.go | 23 ++++++++++++++++++++--- unix/zsyscall_linux_arm64.go | 27 --------------------------- 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/unix/syscall_linux.go b/unix/syscall_linux.go index 3df5f9cb..88c8e042 100644 --- a/unix/syscall_linux.go +++ b/unix/syscall_linux.go @@ -92,13 +92,24 @@ func Unlinkat(dirfd int, path string, flags int) error { //sys utimes(path string, times *[2]Timeval) (err error) -func Utimes(path string, tv []Timeval) (err error) { +func Utimes(path string, tv []Timeval) error { if tv == nil { + err := utimensat(AT_FDCWD, path, nil, 0) + if err != ENOSYS { + return err + } return utimes(path, nil) } if len(tv) != 2 { return EINVAL } + var ts [2]Timespec + ts[0] = NsecToTimespec(TimevalToNsec(tv[0])) + ts[1] = NsecToTimespec(TimevalToNsec(tv[1])) + err := utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) + if err != ENOSYS { + return err + } return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) } diff --git a/unix/syscall_linux_arm64.go b/unix/syscall_linux_arm64.go index c87872e8..42581156 100644 --- a/unix/syscall_linux_arm64.go +++ b/unix/syscall_linux_arm64.go @@ -70,9 +70,6 @@ func Lstat(path string, stat *Stat_t) (err error) { func Getpagesize() int { return 65536 } //sysnb Gettimeofday(tv *Timeval) (err error) -//sysnb Time(t *Time_t) (tt Time_t, err error) - -//sys Utime(path string, buf *Utimbuf) (err error) func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } @@ -91,6 +88,26 @@ func NsecToTimeval(nsec int64) (tv Timeval) { return } +func Time(t *Time_t) (Time_t, error) { + var tv Timeval + err := Gettimeofday(&tv) + if err != nil { + return 0, err + } + if t != nil { + *t = Time_t(tv.Sec) + } + return Time_t(tv.Sec), nil +} + +func Utime(path string, buf *Utimbuf) error { + tv := []Timeval{ + {Sec: buf.Actime}, + {Sec: buf.Modtime}, + } + return Utimes(path, tv) +} + func Pipe(p []int) (err error) { if len(p) != 2 { return EINVAL diff --git a/unix/zsyscall_linux_arm64.go b/unix/zsyscall_linux_arm64.go index 8c5cd137..fb2ff3aa 100644 --- a/unix/zsyscall_linux_arm64.go +++ b/unix/zsyscall_linux_arm64.go @@ -1724,33 +1724,6 @@ func Gettimeofday(tv *Timeval) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func Time(t *Time_t) (tt Time_t, err error) { - r0, _, e1 := RawSyscall(SYS_TIME, uintptr(unsafe.Pointer(t)), 0, 0) - tt = Time_t(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func Utime(path string, buf *Utimbuf) (err error) { - var _p0 *byte - _p0, err = BytePtrFromString(path) - if err != nil { - return - } - _, _, e1 := Syscall(SYS_UTIME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0) - use(unsafe.Pointer(_p0)) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func pipe2(p *[2]_C_int, flags int) (err error) { _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0) if e1 != 0 {