From 14460a8a2b8ad51ddbee772db057e1107d0bec3d Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Tue, 14 Mar 2023 17:10:48 +0100 Subject: [PATCH] fs-util: Add open_parent_at() --- src/basic/fs-util.c | 17 ++++++++++++++--- src/basic/fs-util.h | 5 ++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index 7f1f90f4e9d..19ada73af5a 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -781,12 +781,23 @@ int unlinkat_deallocate(int fd, const char *name, UnlinkDeallocateFlags flags) { return 0; } -int open_parent(const char *path, int flags, mode_t mode) { +int open_parent_at(int dir_fd, const char *path, int flags, mode_t mode) { _cleanup_free_ char *parent = NULL; int r; + assert(dir_fd >= 0 || dir_fd == AT_FDCWD); + assert(path); + r = path_extract_directory(path, &parent); - if (r < 0) + if (r == -EDESTADDRREQ) { + parent = strdup("."); + if (!parent) + return -ENOMEM; + } else if (r == -EADDRNOTAVAIL) { + parent = strdup(path); + if (!parent) + return -ENOMEM; + } else if (r < 0) return r; /* Let's insist on O_DIRECTORY since the parent of a file or directory is a directory. Except if we open an @@ -797,7 +808,7 @@ int open_parent(const char *path, int flags, mode_t mode) { else if (!FLAGS_SET(flags, O_TMPFILE)) flags |= O_DIRECTORY|O_RDONLY; - return RET_NERRNO(open(parent, flags, mode)); + return RET_NERRNO(openat(dir_fd, parent, flags, mode)); } int conservative_renameat( diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h index b66dda01b4a..d08e224aa1b 100644 --- a/src/basic/fs-util.h +++ b/src/basic/fs-util.h @@ -113,7 +113,10 @@ typedef enum UnlinkDeallocateFlags { int unlinkat_deallocate(int fd, const char *name, UnlinkDeallocateFlags flags); -int open_parent(const char *path, int flags, mode_t mode); +int open_parent_at(int dir_fd, const char *path, int flags, mode_t mode); +static inline int open_parent(const char *path, int flags, mode_t mode) { + return open_parent_at(AT_FDCWD, path, flags, mode); +} int conservative_renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath); static inline int conservative_rename(const char *oldpath, const char *newpath) { -- 2.47.3