From 0a2b4af5eb5d4603a43be5f313cd4ff21e4bd9ad Mon Sep 17 00:00:00 2001 From: Peter Waller Date: Tue, 28 Apr 2015 19:47:47 +0100 Subject: [PATCH] unix/amd64: add Utimensat call, pass 0 for flags This CL adds the Utimensat syscall and AT_SYMLINK_NOFOLLOW constant. This is required for setting the access/modification times on symlinks. In addition, it updates the UtimesNano function to pass 0 as the flags parameter, to avoid potentially passing junk. Change-Id: I280645f3f53173628b1e1986bc7a47bac254fcf8 Reviewed-on: https://go-review.googlesource.com/9379 Reviewed-by: Rob Pike --- unix/syscall_linux.go | 11 +++++++++-- unix/types_linux.go | 4 +++- unix/zsyscall_linux_386.go | 4 ++-- unix/zsyscall_linux_amd64.go | 4 ++-- unix/zsyscall_linux_arm.go | 4 ++-- unix/ztypes_linux_386.go | 4 +++- unix/ztypes_linux_amd64.go | 4 +++- unix/ztypes_linux_arm.go | 4 +++- 8 files changed, 27 insertions(+), 12 deletions(-) diff --git a/unix/syscall_linux.go b/unix/syscall_linux.go index 3b37d72d..e23d3867 100644 --- a/unix/syscall_linux.go +++ b/unix/syscall_linux.go @@ -67,13 +67,13 @@ func Utimes(path string, tv []Timeval) (err error) { return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) } -//sys utimensat(dirfd int, path string, times *[2]Timespec) (err error) +//sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) func UtimesNano(path string, ts []Timespec) (err error) { if len(ts) != 2 { return EINVAL } - err = utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0]))) + err = utimensat(AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0) if err != ENOSYS { return err } @@ -87,6 +87,13 @@ func UtimesNano(path string, ts []Timespec) (err error) { return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) } +func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) (err error) { + if len(ts) != 2 { + return EINVAL + } + return utimensat(dirfd, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), flags) +} + //sys futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) func Futimesat(dirfd int, path string, tv []Timeval) (err error) { diff --git a/unix/types_linux.go b/unix/types_linux.go index c2912002..49d9e1fe 100644 --- a/unix/types_linux.go +++ b/unix/types_linux.go @@ -385,7 +385,9 @@ type Ustat_t C.struct_ustat type EpollEvent C.struct_my_epoll_event const ( - _AT_FDCWD = C.AT_FDCWD + AT_FDCWD = C.AT_FDCWD + AT_REMOVEDIR = C.AT_REMOVEDIR + AT_SYMLINK_NOFOLLOW = C.AT_SYMLINK_NOFOLLOW ) // Terminal handling diff --git a/unix/zsyscall_linux_386.go b/unix/zsyscall_linux_386.go index ff03908a..0a5ae953 100644 --- a/unix/zsyscall_linux_386.go +++ b/unix/zsyscall_linux_386.go @@ -82,13 +82,13 @@ func utimes(path string, times *[2]Timeval) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func utimensat(dirfd int, path string, times *[2]Timespec) (err error) { +func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) if err != nil { return } - _, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times))) + _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) use(unsafe.Pointer(_p0)) if e1 != 0 { err = errnoErr(e1) diff --git a/unix/zsyscall_linux_amd64.go b/unix/zsyscall_linux_amd64.go index f1a1185e..362b8153 100644 --- a/unix/zsyscall_linux_amd64.go +++ b/unix/zsyscall_linux_amd64.go @@ -82,13 +82,13 @@ func utimes(path string, times *[2]Timeval) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func utimensat(dirfd int, path string, times *[2]Timespec) (err error) { +func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) if err != nil { return } - _, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times))) + _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) use(unsafe.Pointer(_p0)) if e1 != 0 { err = errnoErr(e1) diff --git a/unix/zsyscall_linux_arm.go b/unix/zsyscall_linux_arm.go index 1af761e0..51d3d7ed 100644 --- a/unix/zsyscall_linux_arm.go +++ b/unix/zsyscall_linux_arm.go @@ -82,13 +82,13 @@ func utimes(path string, times *[2]Timeval) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func utimensat(dirfd int, path string, times *[2]Timespec) (err error) { +func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) if err != nil { return } - _, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times))) + _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0) use(unsafe.Pointer(_p0)) if e1 != 0 { err = errnoErr(e1) diff --git a/unix/ztypes_linux_386.go b/unix/ztypes_linux_386.go index 6644f008..3b1dcc65 100644 --- a/unix/ztypes_linux_386.go +++ b/unix/ztypes_linux_386.go @@ -572,7 +572,9 @@ type EpollEvent struct { } const ( - _AT_FDCWD = -0x64 + AT_FDCWD = -0x64 + AT_SYMLINK_NOFOLLOW = 0x100 + AT_REMOVEDIR = 0x200 ) type Termios struct { diff --git a/unix/ztypes_linux_amd64.go b/unix/ztypes_linux_amd64.go index 37b82c17..8e6bd61e 100644 --- a/unix/ztypes_linux_amd64.go +++ b/unix/ztypes_linux_amd64.go @@ -590,7 +590,9 @@ type EpollEvent struct { } const ( - _AT_FDCWD = -0x64 + AT_FDCWD = -0x64 + AT_SYMLINK_NOFOLLOW = 0x100 + AT_REMOVEDIR = 0x200 ) type Termios struct { diff --git a/unix/ztypes_linux_arm.go b/unix/ztypes_linux_arm.go index e820995a..7a8e0394 100644 --- a/unix/ztypes_linux_arm.go +++ b/unix/ztypes_linux_arm.go @@ -561,7 +561,9 @@ type EpollEvent struct { } const ( - _AT_FDCWD = -0x64 + AT_FDCWD = -0x64 + AT_SYMLINK_NOFOLLOW = 0x100 + AT_REMOVEDIR = 0x200 ) type Termios struct {