From 5545141758dc0e4f1db7e185024a2af162a8e742 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 26 Sep 2022 10:15:03 +0200 Subject: [PATCH] fs-util: Add chown_and_chmod_at() --- src/basic/fs-util.c | 16 ++++++++-------- src/basic/fs-util.h | 5 ++++- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index 6b757bd570..3238ff02f7 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -195,17 +195,17 @@ int readlink_and_make_absolute(const char *p, char **r) { return 0; } -int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) { +int chmod_and_chown_at(int dir_fd, const char *path, mode_t mode, uid_t uid, gid_t gid) { _cleanup_close_ int fd = -1; - assert(path); + if (path) { + /* Let's acquire an O_PATH fd, as precaution to change mode/owner on the same file */ + fd = openat(dir_fd, path, O_PATH|O_CLOEXEC|O_NOFOLLOW); + if (fd < 0) + return -errno; + } - fd = open(path, O_PATH|O_CLOEXEC|O_NOFOLLOW); /* Let's acquire an O_PATH fd, as precaution to change - * mode/owner on the same file */ - if (fd < 0) - return -errno; - - return fchmod_and_chown(fd, mode, uid, gid); + return fchmod_and_chown(path ? fd : dir_fd, mode, uid, gid); } int fchmod_and_chown_with_fallback(int fd, const char *path, mode_t mode, uid_t uid, gid_t gid) { diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h index c4dffc48f3..932d003f19 100644 --- a/src/basic/fs-util.h +++ b/src/basic/fs-util.h @@ -33,7 +33,10 @@ int readlink_malloc(const char *p, char **r); int readlink_value(const char *p, char **ret); int readlink_and_make_absolute(const char *p, char **r); -int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid); +int chmod_and_chown_at(int dir_fd, const char *path, mode_t mode, uid_t uid, gid_t gid); +static inline int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) { + return chmod_and_chown_at(AT_FDCWD, path, mode, uid, gid); +} int fchmod_and_chown_with_fallback(int fd, const char *path, mode_t mode, uid_t uid, gid_t gid); static inline int fchmod_and_chown(int fd, mode_t mode, uid_t uid, gid_t gid) { return fchmod_and_chown_with_fallback(fd, NULL, mode, uid, gid); /* no fallback */