]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic/fileio: add chase_symlinks_and_fopen_unlocked()
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 1 Oct 2020 11:52:16 +0000 (13:52 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 1 Oct 2020 15:52:50 +0000 (17:52 +0200)
src/basic/fileio.c
src/basic/fileio.h
src/basic/fs-util.h

index c3d55d209ac7ede12ceaa70b943023fdb73ddaa0..c5a093a85759c5b900b45e2e4d5a089f90522812 100644 (file)
@@ -940,6 +940,42 @@ int search_and_fopen_nulstr(const char *path, const char *mode, const char *root
         return search_and_fopen_internal(path, mode, root, s, _f);
 }
 
+int chase_symlinks_and_fopen_unlocked(
+                const char *path,
+                const char *root,
+                unsigned chase_flags,
+                const char *open_flags,
+                FILE **ret_file,
+                char **ret_path) {
+
+        _cleanup_close_ int fd = -1;
+        _cleanup_free_ char *final_path = NULL;
+        int mode_flags, r;
+        FILE *f;
+
+        assert(path);
+        assert(open_flags);
+        assert(ret_file);
+
+        mode_flags = mode_to_flags(open_flags);
+        if (mode_flags < 0)
+                return mode_flags;
+
+        fd = chase_symlinks_and_open(path, root, chase_flags, mode_flags, ret_path ? &final_path : NULL);
+        if (fd < 0)
+                return fd;
+
+        r = fdopen_unlocked(fd, open_flags, &f);
+        if (r < 0)
+                return r;
+        TAKE_FD(fd);
+
+        *ret_file = f;
+        if (ret_path)
+                *ret_path = TAKE_PTR(final_path);
+        return 0;
+}
+
 int fflush_and_check(FILE *f) {
         assert(f);
 
index 7d58fa7cfc24d51033edb97a3f7a4fec6d6aa5f1..9cba5a90e3f8688bbc9c63ce7f635e58e365354b 100644 (file)
@@ -81,6 +81,14 @@ int xfopenat(int dir_fd, const char *path, const char *mode, int flags, FILE **r
 int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f);
 int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f);
 
+int chase_symlinks_and_fopen_unlocked(
+                const char *path,
+                const char *root,
+                unsigned chase_flags,
+                const char *open_flags,
+                FILE **ret_file,
+                char **ret_path);
+
 int fflush_and_check(FILE *f);
 int fflush_sync_and_check(FILE *f);
 
index eb6e1eee4fa018a652e8bd1b4f259a1f95d8d3b1..2a785f690d94e22847e5a06555fb69314e9bb34e 100644 (file)
@@ -79,7 +79,7 @@ enum {
         CHASE_PREFIX_ROOT = 1 << 0, /* The specified path will be prefixed by the specified root before beginning the iteration */
         CHASE_NONEXISTENT = 1 << 1, /* It's OK if the path doesn't actually exist. */
         CHASE_NO_AUTOFS   = 1 << 2, /* Return -EREMOTE if autofs mount point found */
-        CHASE_SAFE        = 1 << 3, /* Return EPERM if we ever traverse from unprivileged to privileged files or directories */
+        CHASE_SAFE        = 1 << 3, /* Return -EPERM if we ever traverse from unprivileged to privileged files or directories */
         CHASE_TRAIL_SLASH = 1 << 4, /* Any trailing slash will be preserved */
         CHASE_STEP        = 1 << 5, /* Just execute a single step of the normalization */
         CHASE_NOFOLLOW    = 1 << 6, /* Do not follow the path's right-most component. With ret_fd, when the path's