aboutsummaryrefslogtreecommitdiff
path: root/src/syscall/syscall_linux.go
diff options
context:
space:
mode:
authorTobias Klauser <tklauser@distanz.ch>2023-11-07 13:10:48 +0100
committerGopher Robot <gobot@golang.org>2023-11-08 17:55:49 +0000
commit07c388f17c039c0bb9a3fd0fd70bf5494aa7ee2c (patch)
treebac510e9fda1c963edc908c07b2524a88518e583 /src/syscall/syscall_linux.go
parent0889b39ff12405c37ce23af5b65263ab4b31899c (diff)
downloadgo-07c388f17c039c0bb9a3fd0fd70bf5494aa7ee2c.tar.xz
syscall: use fchmodat2 in Fchmodat
The fchmodat2 syscall was added in Linux kernel 6.6. Mirror the implementation in golang.org/x/sys/unix.Fchmodat (CL 539635) and use fchmodat2 in Fchmodat if flags are given. It will return ENOSYS on older kernels (or EINVAL or any other bogus error in some container implementations). Also update ztypes_linux_$GOARCH.go for all linux platforms to add _AT_EMPTY_PATH. It was added to linux/types in CL 407694 but was only updated for linux/loong64 at that time. Updates #61636 Change-Id: I863d06e35cd366f1cf99052e9f77c22ab8168b3f Reviewed-on: https://go-review.googlesource.com/c/go/+/540435 Reviewed-by: Mauri de Souza Meneguzzo <mauri870@gmail.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Heschi Kreinick <heschi@google.com> Reviewed-by: Bryan Mills <bcmills@google.com> Auto-Submit: Tobias Klauser <tobias.klauser@gmail.com>
Diffstat (limited to 'src/syscall/syscall_linux.go')
-rw-r--r--src/syscall/syscall_linux.go24
1 files changed, 16 insertions, 8 deletions
diff --git a/src/syscall/syscall_linux.go b/src/syscall/syscall_linux.go
index 96ad4fbe3f..b6e84203e8 100644
--- a/src/syscall/syscall_linux.go
+++ b/src/syscall/syscall_linux.go
@@ -241,15 +241,23 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
}
//sys fchmodat(dirfd int, path string, mode uint32) (err error)
+//sys fchmodat2(dirfd int, path string, mode uint32, flags int) (err error) = _SYS_fchmodat2
-func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
- // Linux fchmodat doesn't support the flags parameter. Mimic glibc's behavior
- // and check the flags. Otherwise the mode would be applied to the symlink
- // destination which is not what the user expects.
- if flags&^_AT_SYMLINK_NOFOLLOW != 0 {
- return EINVAL
- } else if flags&_AT_SYMLINK_NOFOLLOW != 0 {
- return EOPNOTSUPP
+func Fchmodat(dirfd int, path string, mode uint32, flags int) error {
+ // Linux fchmodat doesn't support the flags parameter, but fchmodat2 does.
+ // Try fchmodat2 if flags are specified.
+ if flags != 0 {
+ err := fchmodat2(dirfd, path, mode, flags)
+ if err == ENOSYS {
+ // fchmodat2 isn't available. If the flags are known to be valid,
+ // return EOPNOTSUPP to indicate that fchmodat doesn't support them.
+ if flags&^(_AT_SYMLINK_NOFOLLOW|_AT_EMPTY_PATH) != 0 {
+ return EINVAL
+ } else if flags&(_AT_SYMLINK_NOFOLLOW|_AT_EMPTY_PATH) != 0 {
+ return EOPNOTSUPP
+ }
+ }
+ return err
}
return fchmodat(dirfd, path, mode)
}