Jelajahi Sumber

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 <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Riku Voipio 9 tahun lalu
induk
melakukan
7a56174f00
3 mengubah file dengan 32 tambahan dan 31 penghapusan
  1. 12 1
      unix/syscall_linux.go
  2. 20 3
      unix/syscall_linux_arm64.go
  3. 0 27
      unix/zsyscall_linux_arm64.go

+ 12 - 1
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])))
 }
 

+ 20 - 3
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

+ 0 - 27
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 {