From 64077c9b5642ac67ce07bc05738eb432a9029f93 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Mon, 3 Aug 2020 22:17:34 +0200 Subject: [PATCH] unix: add Faccessat2 and use it in Faccessat if available Linux kernel 5.8 added the faccessat2 syscall taking a flags argument. Attempt to use it in Faccessat and fall back to the existing implementation mimicking glibc faccessat. Tested on Debian Buster with manually built Linux kernel 5.8 Suggested by Ian Lance Taylor. Change-Id: Ia14f744a63dde7ff2dea34935cabc62937de9cb5 Reviewed-on: https://go-review.googlesource.com/c/sys/+/246537 Run-TryBot: Tobias Klauser TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- unix/syscall_linux.go | 13 +++++++++---- unix/zsyscall_linux.go | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/unix/syscall_linux.go b/unix/syscall_linux.go index fad483bb..ab167368 100644 --- a/unix/syscall_linux.go +++ b/unix/syscall_linux.go @@ -1965,10 +1965,15 @@ func isGroupMember(gid int) bool { } //sys faccessat(dirfd int, path string, mode uint32) (err error) +//sys Faccessat2(dirfd int, path string, mode uint32, flags int) (err error) func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { - if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 { - return EINVAL + if flags == 0 { + return faccessat(dirfd, path, mode) + } + + if err := Faccessat2(dirfd, path, mode, flags); err != ENOSYS { + return err } // The Linux kernel faccessat system call does not take any flags. @@ -1977,8 +1982,8 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { // Because people naturally expect syscall.Faccessat to act // like C faccessat, we do the same. - if flags == 0 { - return faccessat(dirfd, path, mode) + if flags & ^(AT_SYMLINK_NOFOLLOW|AT_EACCESS) != 0 { + return EINVAL } var st Stat_t diff --git a/unix/zsyscall_linux.go b/unix/zsyscall_linux.go index f6603de4..4eec7a79 100644 --- a/unix/zsyscall_linux.go +++ b/unix/zsyscall_linux.go @@ -1821,6 +1821,21 @@ func faccessat(dirfd int, path string, mode uint32) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func Faccessat2(dirfd int, path string, mode uint32, flags int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + _, _, e1 := Syscall6(SYS_FACCESSAT2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(pathname)