]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
conf-files: introduce CONF_FILES_CHASE_BASENAME flag
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 27 Jun 2025 00:20:08 +0000 (09:20 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 27 Jun 2025 19:13:43 +0000 (04:13 +0900)
Previously, when a root directory is specified to conf_files_list() and
friends, the last component of each result was not resolved, even though
they internally chases the last component. So the caller needs to chase
the path again when the file is used.

This introduce a new flag that makes the whole path of each result is
resolved, hence caller can use it as is.

src/basic/conf-files.c
src/basic/conf-files.h
src/test/test-conf-files.c

index 85b9ea8e5f3b670029310a451cad9439730e388f..043fda1cbe60047b635953443fe133e43011f092 100644 (file)
@@ -164,6 +164,9 @@ static int files_add(
                 if (!n)
                         return log_oom_debug();
 
+                if (FLAGS_SET(flags, CONF_FILES_CHASE_BASENAME))
+                        free_and_replace(p, resolved_path);
+
                 r = hashmap_ensure_put(files, &string_hash_ops_free_free, n, p);
                 if (r < 0) {
                         assert(r == -ENOMEM);
index a1b9af0ea2c04e5dde4b3a6066766af31ac59cd8..86a76088334edd6d7f6fe71df01ce9dcfbcdadef 100644 (file)
@@ -8,8 +8,9 @@ typedef enum ConfFilesFlags {
         CONF_FILES_REGULAR                  = 1 << 1,
         CONF_FILES_DIRECTORY                = 1 << 2,
         CONF_FILES_BASENAME                 = 1 << 3,
-        CONF_FILES_FILTER_MASKED_BY_SYMLINK = 1 << 4,
-        CONF_FILES_FILTER_MASKED_BY_EMPTY   = 1 << 5,
+        CONF_FILES_CHASE_BASENAME           = 1 << 4, /* If set, also resolve symlink files in config directories. */
+        CONF_FILES_FILTER_MASKED_BY_SYMLINK = 1 << 5,
+        CONF_FILES_FILTER_MASKED_BY_EMPTY   = 1 << 6,
         CONF_FILES_FILTER_MASKED            = CONF_FILES_FILTER_MASKED_BY_SYMLINK | CONF_FILES_FILTER_MASKED_BY_EMPTY,
 } ConfFilesFlags;
 
index 3901831e8374cc2afd20657be60be791fcf60110..342b90263e97050ea6ab0c6cd740b236a8553750 100644 (file)
@@ -185,6 +185,14 @@ TEST(conf_files_list) {
                                                  strjoina(search3, "relative-non-empty.conf"))));
         result = strv_free(result);
 
+        ASSERT_OK(conf_files_list(&result, /* suffix = */ NULL, /* root = */ NULL, CONF_FILES_REGULAR | CONF_FILES_CHASE_BASENAME, search3));
+        strv_print(result);
+        ASSERT_TRUE(strv_equal(result, STRV_MAKE(strjoina(t2, "/absolute-empty.real"),
+                                                 strjoina(t2, "/absolute-non-empty.real"),
+                                                 strjoina(t2, "/relative-empty.real"),
+                                                 strjoina(t2, "/relative-non-empty.real"))));
+        result = strv_free(result);
+
         ASSERT_OK(conf_files_list(&result, /* suffix = */ NULL, t, CONF_FILES_FILTER_MASKED, "/dir3/"));
         strv_print(result);
         ASSERT_TRUE(strv_equal(result, STRV_MAKE(strjoina(search3, "absolute-non-empty-for-root.conf"),
@@ -213,6 +221,14 @@ TEST(conf_files_list) {
                                                  strjoina(search3, "relative-non-empty-for-root.conf"))));
         result = strv_free(result);
 
+        ASSERT_OK(conf_files_list(&result, /* suffix = */ NULL, t, CONF_FILES_REGULAR | CONF_FILES_CHASE_BASENAME, "/dir3/"));
+        strv_print(result);
+        ASSERT_TRUE(strv_equal(result, STRV_MAKE(strjoina(t, "/absolute-empty-for-root.real"),
+                                                 strjoina(t, "/absolute-non-empty-for-root.real"),
+                                                 strjoina(t, "/relative-empty-for-root.real"),
+                                                 strjoina(t, "/relative-non-empty-for-root.real"))));
+        result = strv_free(result);
+
         ASSERT_OK(conf_files_list_at(&result, /* suffix = */ NULL, AT_FDCWD, CONF_FILES_FILTER_MASKED, search3));
         strv_print(result);
         ASSERT_TRUE(strv_equal(result, STRV_MAKE(strjoina(search3, "absolute-non-empty.conf"),
@@ -241,6 +257,14 @@ TEST(conf_files_list) {
                                                  strjoina(search3, "relative-non-empty.conf"))));
         result = strv_free(result);
 
+        ASSERT_OK(conf_files_list_at(&result, /* suffix = */ NULL, AT_FDCWD, CONF_FILES_REGULAR | CONF_FILES_CHASE_BASENAME, search3));
+        strv_print(result);
+        ASSERT_TRUE(strv_equal(result, STRV_MAKE(strjoina(t2, "/absolute-empty.real"),
+                                                 strjoina(t2, "/absolute-non-empty.real"),
+                                                 strjoina(t2, "/relative-empty.real"),
+                                                 strjoina(t2, "/relative-non-empty.real"))));
+        result = strv_free(result);
+
         ASSERT_OK(conf_files_list_at(&result, /* suffix = */ NULL, tfd, CONF_FILES_FILTER_MASKED, "/dir3/"));
         strv_print(result);
         ASSERT_TRUE(strv_equal(result, STRV_MAKE("dir3/absolute-non-empty-for-root.conf",
@@ -269,6 +293,14 @@ TEST(conf_files_list) {
                                                  "dir3/relative-non-empty-for-root.conf")));
         result = strv_free(result);
 
+        ASSERT_OK(conf_files_list_at(&result, /* suffix = */ NULL, tfd, CONF_FILES_REGULAR | CONF_FILES_CHASE_BASENAME, "/dir3/"));
+        strv_print(result);
+        ASSERT_TRUE(strv_equal(result, STRV_MAKE("absolute-empty-for-root.real",
+                                                 "absolute-non-empty-for-root.real",
+                                                 "relative-empty-for-root.real",
+                                                 "relative-non-empty-for-root.real")));
+        result = strv_free(result);
+
         /* filename only */
         assert_se(conf_files_list_strv(&result, ".conf", NULL, CONF_FILES_FILTER_MASKED | CONF_FILES_BASENAME, STRV_MAKE_CONST(search1, search2)) >= 0);
         strv_print(result);