summaryrefslogtreecommitdiff
path: root/src/basic/fs-util.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-04-18 16:19:46 +0200
committerSven Eden <yamakuzure@gmx.net>2018-08-24 16:47:08 +0200
commita30b675e8c958eb54b1af8162a400a27ffc647f0 (patch)
tree4e5bf7340c4dacfd5c740aa0cb39e37066d98554 /src/basic/fs-util.c
parente5e0c80fdfa8861931df799574d5a60c96b6aa13 (diff)
path-lookup: properly chase paths when reducing with root dir (#8750)
Let's make this correct.
Diffstat (limited to 'src/basic/fs-util.c')
-rw-r--r--src/basic/fs-util.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c
index 5bf1413c1..44185b16b 100644
--- a/src/basic/fs-util.c
+++ b/src/basic/fs-util.c
@@ -966,6 +966,46 @@ int chase_symlinks_and_opendir(
return 0;
}
+int chase_symlinks_and_stat(
+ const char *path,
+ const char *root,
+ unsigned chase_flags,
+ char **ret_path,
+ struct stat *ret_stat) {
+
+ _cleanup_close_ int path_fd = -1;
+ _cleanup_free_ char *p = NULL;
+
+ assert(path);
+ assert(ret_stat);
+
+ if (chase_flags & CHASE_NONEXISTENT)
+ return -EINVAL;
+
+ if (empty_or_root(root) && !ret_path && (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE)) == 0) {
+ /* Shortcut this call if none of the special features of this call are requested */
+ if (stat(path, ret_stat) < 0)
+ return -errno;
+
+ return 1;
+ }
+
+ path_fd = chase_symlinks(path, root, chase_flags|CHASE_OPEN, ret_path ? &p : NULL);
+ if (path_fd < 0)
+ return path_fd;
+
+ if (fstat(path_fd, ret_stat) < 0)
+ return -errno;
+
+ if (ret_path)
+ *ret_path = TAKE_PTR(p);
+
+ if (chase_flags & CHASE_OPEN)
+ return TAKE_FD(path_fd);
+
+ return 1;
+}
+
int access_fd(int fd, int mode) {
char p[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1];
int r;