]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
chase-symlinks: add chase_symlinks_and_access() helper
authorLennart Poettering <lennart@poettering.net>
Mon, 22 Aug 2022 09:36:12 +0000 (11:36 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 22 Aug 2022 11:40:13 +0000 (13:40 +0200)
This is similar to chase_symlinks_and_access() but wraps access() rather
than stat()

src/basic/chase-symlinks.c
src/basic/chase-symlinks.h

index 2561da0e8c1d6abb142b3a7ff3a4d9acdf3e7bb2..a5d89e134974193957f92243e35dfa52cec88f01 100644 (file)
@@ -530,6 +530,49 @@ int chase_symlinks_and_stat(
         return 1;
 }
 
+int chase_symlinks_and_access(
+                const char *path,
+                const char *root,
+                ChaseSymlinksFlags chase_flags,
+                int access_mode,
+                char **ret_path,
+                int *ret_fd) {
+
+        _cleanup_close_ int path_fd = -1;
+        _cleanup_free_ char *p = NULL;
+        int r;
+
+        assert(path);
+
+        if (chase_flags & (CHASE_NONEXISTENT|CHASE_STEP))
+                return -EINVAL;
+
+        if (empty_or_root(root) && !ret_path && (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE)) == 0 && !ret_fd) {
+                /* Shortcut this call if none of the special features of this call are requested */
+
+                if (faccessat(AT_FDCWD, path, access_mode, FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? AT_SYMLINK_NOFOLLOW : 0) < 0)
+                        return -errno;
+
+                return 1;
+        }
+
+        r = chase_symlinks(path, root, chase_flags, ret_path ? &p : NULL, &path_fd);
+        if (r < 0)
+                return r;
+        assert(path_fd >= 0);
+
+        r = access_fd(path_fd, access_mode);
+        if (r < 0)
+                return r;
+
+        if (ret_path)
+                *ret_path = TAKE_PTR(p);
+        if (ret_fd)
+                *ret_fd = TAKE_FD(path_fd);
+
+        return 1;
+}
+
 int chase_symlinks_and_fopen_unlocked(
                 const char *path,
                 const char *root,
index 491138a698bf24c8dfb4cfda8592dbad41fcaeea..7e45b0cbab5b02aca8c3fc3ce439d6117743df3c 100644 (file)
@@ -28,5 +28,5 @@ int chase_symlinks(const char *path_with_prefix, const char *root, ChaseSymlinks
 int chase_symlinks_and_open(const char *path, const char *root, ChaseSymlinksFlags chase_flags, int open_flags, char **ret_path);
 int chase_symlinks_and_opendir(const char *path, const char *root, ChaseSymlinksFlags chase_flags, char **ret_path, DIR **ret_dir);
 int chase_symlinks_and_stat(const char *path, const char *root, ChaseSymlinksFlags chase_flags, char **ret_path, struct stat *ret_stat, int *ret_fd);
-
+int chase_symlinks_and_access(const char *path, const char *root, ChaseSymlinksFlags chase_flags, int access_mode, char **ret_path, int *ret_fd);
 int chase_symlinks_and_fopen_unlocked(const char *path, const char *root, ChaseSymlinksFlags chase_flags, const char *open_flags, char **ret_path, FILE **ret_file);