]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
chase-symlinks: new chase_symlinks_and_unlink()
authorLudwig Nussel <ludwig.nussel@suse.de>
Mon, 9 Jan 2023 16:58:57 +0000 (17:58 +0100)
committerLudwig Nussel <ludwig.nussel@suse.de>
Thu, 19 Jan 2023 13:11:12 +0000 (14:11 +0100)
src/basic/chase-symlinks.c
src/basic/chase-symlinks.h
src/test/test-fs-util.c

index a0134fd330bb3365006874b0b6b845c8394010cd..4cc0a01df8ef0a289b8ef034661ed5574fe353f6 100644 (file)
@@ -689,3 +689,42 @@ int chase_symlinks_and_fopen_unlocked(
 
         return 0;
 }
+
+int chase_symlinks_and_unlink(
+                const char *path,
+                const char *root,
+                ChaseSymlinksFlags chase_flags,
+                int unlink_flags,
+                char **ret_path) {
+
+        _cleanup_free_ char *p = NULL, *rp = NULL, *dir = NULL, *fname = NULL;
+        _cleanup_close_ int fd = -1;
+        int r;
+
+        assert(path);
+
+        r = path_extract_directory(path, &dir);
+        if (r < 0)
+                return r;
+        r = path_extract_filename(path, &fname);
+        if (r < 0)
+                return r;
+
+        fd = chase_symlinks_and_open(dir, root, chase_flags, O_PATH|O_DIRECTORY|O_CLOEXEC, ret_path ? &p : NULL);
+        if (fd < 0)
+                return fd;
+
+        if (p) {
+                rp = path_join(p, fname);
+                if (!rp)
+                        return -ENOMEM;
+        }
+
+        if (unlinkat(fd, fname, unlink_flags) < 0)
+                return -errno;
+
+        if (ret_path)
+                *ret_path = TAKE_PTR(rp);
+
+        return 0;
+}
index af0fcf155a26973c3adedc59ce4faee975cb1f83..be5e2bb69650135c9ed55178bd40ff3fa171d40b 100644 (file)
@@ -34,5 +34,6 @@ int chase_symlinks_and_opendir(const char *path, const char *root, ChaseSymlinks
 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);
+int chase_symlinks_and_unlink(const char *path, const char *root, ChaseSymlinksFlags chase_flags, int unlink_flags, char **ret_path);
 
 int chase_symlinks_at(int dir_fd, const char *path, ChaseSymlinksFlags flags, char **ret_path, int *ret_fd);
index 38299ce7298291f5f458be7e1547393b1351e9c6..668a44733bc93a65b525e34d94336131bd9c152e 100644 (file)
@@ -330,6 +330,13 @@ TEST(chase_symlinks) {
                 assert_se(sd_id128_equal(a, b));
         }
 
+        assert_se(lstat(p, &st) >= 0);
+        r = chase_symlinks_and_unlink(p, NULL, 0, 0,  &result);
+        assert_se(path_equal(result, p));
+        result = mfree(result);
+        assert_se(r == 0);
+        assert_se(lstat(p, &st) == -1 && errno == ENOENT);
+
         /* Test CHASE_NOFOLLOW */
 
         p = strjoina(temp, "/target");