summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/basic/fd-util.c13
-rw-r--r--src/basic/fd-util.h7
2 files changed, 16 insertions, 4 deletions
diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c
index 907bfeb600..ecbe58a9f8 100644
--- a/src/basic/fd-util.c
+++ b/src/basic/fd-util.c
@@ -891,12 +891,21 @@ int fd_get_diskseq(int fd, uint64_t *ret) {
return 0;
}
-int dir_fd_is_root(int dir_fd) {
+int path_is_root_at(int dir_fd, const char *path) {
STRUCT_NEW_STATX_DEFINE(st);
STRUCT_NEW_STATX_DEFINE(pst);
+ _cleanup_close_ int fd = -EBADF;
int r;
- assert(dir_fd >= 0);
+ assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
+
+ if (!isempty(path)) {
+ fd = openat(dir_fd, path, O_PATH|O_CLOEXEC);
+ if (fd < 0)
+ return -errno;
+
+ dir_fd = fd;
+ }
r = statx_fallback(dir_fd, ".", 0, STATX_TYPE|STATX_INO|STATX_MNT_ID, &st.sx);
if (r == -ENOTDIR)
diff --git a/src/basic/fd-util.h b/src/basic/fd-util.h
index 2f59e334c5..c870a1b899 100644
--- a/src/basic/fd-util.h
+++ b/src/basic/fd-util.h
@@ -101,9 +101,12 @@ int fd_is_opath(int fd);
int read_nr_open(void);
int fd_get_diskseq(int fd, uint64_t *ret);
-int dir_fd_is_root(int dir_fd);
+int path_is_root_at(int dir_fd, const char *path);
+static inline int dir_fd_is_root(int dir_fd) {
+ return path_is_root_at(dir_fd, NULL);
+}
static inline int dir_fd_is_root_or_cwd(int dir_fd) {
- return dir_fd == AT_FDCWD ? true : dir_fd_is_root(dir_fd);
+ return dir_fd == AT_FDCWD ? true : path_is_root_at(dir_fd, NULL);
}
/* The maximum length a buffer for a /proc/self/fd/<fd> path needs */