diff options
Diffstat (limited to 'src/libnm-systemd-shared/src/basic/fs-util.c')
-rw-r--r-- | src/libnm-systemd-shared/src/basic/fs-util.c | 57 |
1 files changed, 30 insertions, 27 deletions
diff --git a/src/libnm-systemd-shared/src/basic/fs-util.c b/src/libnm-systemd-shared/src/basic/fs-util.c index 6b757bd570..a895f4f2df 100644 --- a/src/libnm-systemd-shared/src/basic/fs-util.c +++ b/src/libnm-systemd-shared/src/basic/fs-util.c @@ -32,7 +32,6 @@ #include "tmpfile-util.h" #include "umask-util.h" #include "user-util.h" -#include "util.h" int unlink_noerrno(const char *path) { PROTECT_ERRNO; @@ -175,37 +174,41 @@ int readlink_value(const char *p, char **ret) { return 0; } -int readlink_and_make_absolute(const char *p, char **r) { +int readlink_and_make_absolute(const char *p, char **ret) { _cleanup_free_ char *target = NULL; - char *k; - int j; + int r; assert(p); - assert(r); - - j = readlink_malloc(p, &target); - if (j < 0) - return j; + assert(ret); - k = file_in_same_dir(p, target); - if (!k) - return -ENOMEM; + r = readlink_malloc(p, &target); + if (r < 0) + return r; - *r = k; - return 0; + return file_in_same_dir(p, target, ret); } -int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) { - _cleanup_close_ int fd = -1; +int chmod_and_chown_at(int dir_fd, const char *path, mode_t mode, uid_t uid, gid_t gid) { + _cleanup_close_ int fd = -EBADF; - assert(path); + assert(dir_fd >= 0 || dir_fd == AT_FDCWD); - 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; + 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; + dir_fd = fd; + + } else if (dir_fd == AT_FDCWD) { + /* Let's acquire an O_PATH fd of the current directory */ + fd = openat(dir_fd, ".", O_PATH|O_CLOEXEC|O_NOFOLLOW|O_DIRECTORY); + if (fd < 0) + return -errno; + dir_fd = fd; + } - return fchmod_and_chown(fd, mode, uid, gid); + return fchmod_and_chown(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) { @@ -351,7 +354,7 @@ int fd_warn_permissions(const char *path, int fd) { } int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) { - _cleanup_close_ int fd = -1; + _cleanup_close_ int fd = -EBADF; int r, ret; assert(path); @@ -675,7 +678,7 @@ void unlink_tempfilep(char (*p)[]) { } int unlinkat_deallocate(int fd, const char *name, UnlinkDeallocateFlags flags) { - _cleanup_close_ int truncate_fd = -1; + _cleanup_close_ int truncate_fd = -EBADF; struct stat st; off_t l, bs; @@ -806,7 +809,7 @@ int conservative_renameat( int olddirfd, const char *oldpath, int newdirfd, const char *newpath) { - _cleanup_close_ int old_fd = -1, new_fd = -1; + _cleanup_close_ int old_fd = -EBADF, new_fd = -EBADF; struct stat old_stat, new_stat; /* Renames the old path to thew new path, much like renameat() — except if both are regular files and @@ -902,7 +905,7 @@ int posix_fallocate_loop(int fd, uint64_t offset, uint64_t size) { /* On EINTR try a couple of times more, but protect against busy looping * (not more than 16 times per 10s) */ - rl = (RateLimit) { 10 * USEC_PER_SEC, 16 }; + rl = (const RateLimit) { 10 * USEC_PER_SEC, 16 }; while (ratelimit_below(&rl)) { r = posix_fallocate(fd, offset, size); if (r != EINTR) @@ -988,7 +991,7 @@ int parse_cifs_service( } int open_mkdir_at(int dirfd, const char *path, int flags, mode_t mode) { - _cleanup_close_ int fd = -1, parent_fd = -1; + _cleanup_close_ int fd = -EBADF, parent_fd = -EBADF; _cleanup_free_ char *fname = NULL; bool made; int r; |