basic/fs-util: prefer fchmodat2 in fchmod_opath

Co-authored-by: Mike Yuan <me@yhndnzj.com>
This commit is contained in:
Arseny Maslennikov
2023-11-02 00:26:22 +08:00
committed by Mike Yuan
co-authored by Mike Yuan
parent c21566d90b
commit adecfb3bc0
+16 -2
View File
@@ -288,8 +288,22 @@ int fchmod_umask(int fd, mode_t m) {
int fchmod_opath(int fd, mode_t m) {
/* This function operates also on fd that might have been opened with
* O_PATH. Indeed fchmodat() doesn't have the AT_EMPTY_PATH flag like
* fchownat() does. */
* O_PATH. The tool set we have is non-intuitive:
* - fchmod(2) only operates on open files (i. e., fds with an open file description);
* - fchmodat(2) does not have a flag arg like fchownat(2) does, so no way to pass AT_EMPTY_PATH;
* + it should not be confused with the libc fchmodat(3) interface, which adds 4th flag argument,
* but does not support AT_EMPTY_PATH (only supports AT_SYMLINK_NOFOLLOW);
* - fchmodat2(2) supports all the AT_* flags, but is still very recent.
*
* We try to use fchmodat2(), and, if it is not supported, resort
* to the /proc/self/fd dance. */
assert(fd >= 0);
if (fchmodat2(fd, "", m, AT_EMPTY_PATH) >= 0)
return 0;
if (!IN_SET(errno, ENOSYS, EPERM)) /* Some container managers block unknown syscalls with EPERM */
return -errno;
if (chmod(FORMAT_PROC_FD_PATH(fd), m) < 0) {
if (errno != ENOENT)