From: Lennart Poettering Date: Mon, 22 Aug 2022 09:36:12 +0000 (+0200) Subject: chase-symlinks: add chase_symlinks_and_access() helper X-Git-Tag: v252-rc1~377^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2b2caea21df4f5c2b91888c037b9bc04da40dec3;p=thirdparty%2Fsystemd.git chase-symlinks: add chase_symlinks_and_access() helper This is similar to chase_symlinks_and_access() but wraps access() rather than stat() --- diff --git a/src/basic/chase-symlinks.c b/src/basic/chase-symlinks.c index 2561da0e8c1..a5d89e13497 100644 --- a/src/basic/chase-symlinks.c +++ b/src/basic/chase-symlinks.c @@ -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, diff --git a/src/basic/chase-symlinks.h b/src/basic/chase-symlinks.h index 491138a698b..7e45b0cbab5 100644 --- a/src/basic/chase-symlinks.h +++ b/src/basic/chase-symlinks.h @@ -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);