@@ -61,15 +61,23 @@ func FanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname string) (
61
61
}
62
62
63
63
//sys fchmodat(dirfd int, path string, mode uint32) (err error)
64
-
65
- func Fchmodat (dirfd int , path string , mode uint32 , flags int ) (err error ) {
66
- // Linux fchmodat doesn't support the flags parameter. Mimick glibc's behavior
67
- // and check the flags. Otherwise the mode would be applied to the symlink
68
- // destination which is not what the user expects.
69
- if flags &^AT_SYMLINK_NOFOLLOW != 0 {
70
- return EINVAL
71
- } else if flags & AT_SYMLINK_NOFOLLOW != 0 {
72
- return EOPNOTSUPP
64
+ //sys fchmodat2(dirfd int, path string, mode uint32, flags int) (err error)
65
+
66
+ func Fchmodat (dirfd int , path string , mode uint32 , flags int ) error {
67
+ // Linux fchmodat doesn't support the flags parameter, but fchmodat2 does.
68
+ // Try fchmodat2 if flags are specified.
69
+ if flags != 0 {
70
+ err := fchmodat2 (dirfd , path , mode , flags )
71
+ if err == ENOSYS {
72
+ // fchmodat2 isn't available. If the flags are known to be valid,
73
+ // return EOPNOTSUPP to indicate that fchmodat doesn't support them.
74
+ if flags &^(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH ) != 0 {
75
+ return EINVAL
76
+ } else if flags & (AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH ) != 0 {
77
+ return EOPNOTSUPP
78
+ }
79
+ }
80
+ return err
73
81
}
74
82
return fchmodat (dirfd , path , mode )
75
83
}
0 commit comments