From: Yu Watanabe Date: Sat, 28 Jun 2025 11:55:11 +0000 (+0900) Subject: path-util: move empty_or_root_to_null() from chase.c X-Git-Tag: v258-rc1~222^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8ce463639a67b68ba5b4cec50cf36e138a9b0f0e;p=thirdparty%2Fsystemd.git path-util: move empty_or_root_to_null() from chase.c And rename it to empty_or_root_harder_to_null(), as it also checks if the input path effectively points to the root by calling path_is_root(). This also adds simple test cases for the function. --- diff --git a/src/basic/chase.c b/src/basic/chase.c index 34423cc3004..8fd7e67559e 100644 --- a/src/basic/chase.c +++ b/src/basic/chase.c @@ -565,27 +565,6 @@ chased_one: return 0; } -static int empty_or_root_to_null(const char **path) { - int r; - - assert(path); - - /* This nullifies the input path when the path is empty or points to "/". */ - - if (empty_or_root(*path)) { - *path = NULL; - return 0; - } - - r = path_is_root(*path); - if (r < 0) - return r; - if (r > 0) - *path = NULL; - - return 0; -} - int chase(const char *path, const char *root, ChaseFlags flags, char **ret_path, int *ret_fd) { _cleanup_free_ char *root_abs = NULL, *absolute = NULL, *p = NULL; _cleanup_close_ int fd = -EBADF, pfd = -EBADF; @@ -596,7 +575,7 @@ int chase(const char *path, const char *root, ChaseFlags flags, char **ret_path, if (isempty(path)) return -EINVAL; - r = empty_or_root_to_null(&root); + r = empty_or_root_harder_to_null(&root); if (r < 0) return r; @@ -696,7 +675,7 @@ int chaseat_prefix_root(const char *path, const char *root, char **ret) { if (!path_is_absolute(path)) { _cleanup_free_ char *root_abs = NULL; - r = empty_or_root_to_null(&root); + r = empty_or_root_harder_to_null(&root); if (r < 0 && r != -ENOENT) return r; @@ -735,7 +714,7 @@ int chase_extract_filename(const char *path, const char *root, char **ret) { if (!path_is_absolute(path)) return -EINVAL; - r = empty_or_root_to_null(&root); + r = empty_or_root_harder_to_null(&root); if (r < 0 && r != -ENOENT) return r; diff --git a/src/basic/path-util.c b/src/basic/path-util.c index dd23d3f6ab0..36cf9a16491 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -1406,6 +1406,27 @@ const char* empty_to_root(const char *path) { return isempty(path) ? "/" : path; } +int empty_or_root_harder_to_null(const char **path) { + int r; + + assert(path); + + /* This nullifies the input path when the path is empty or points to "/". */ + + if (empty_or_root(*path)) { + *path = NULL; + return 0; + } + + r = path_is_root(*path); + if (r < 0) + return r; + if (r > 0) + *path = NULL; + + return 0; +} + bool path_strv_contains(char * const *l, const char *path) { assert(path); diff --git a/src/basic/path-util.h b/src/basic/path-util.h index a209223bccd..45518c07e50 100644 --- a/src/basic/path-util.h +++ b/src/basic/path-util.h @@ -179,6 +179,7 @@ static inline const char* skip_dev_prefix(const char *p) { bool empty_or_root(const char *path) _pure_; const char* empty_to_root(const char *path) _pure_; +int empty_or_root_harder_to_null(const char **path); bool path_strv_contains(char * const *l, const char *path); bool prefixed_path_strv_contains(char * const *l, const char *path); diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c index ea025cb1354..cbe0341fe4b 100644 --- a/src/test/test-path-util.c +++ b/src/test/test-path-util.c @@ -1238,6 +1238,42 @@ TEST(empty_or_root) { assert_se(!empty_or_root("//yy//")); } +TEST(empty_or_root_harder_to_null) { + const char *p; + + p = NULL; + ASSERT_OK(empty_or_root_harder_to_null(&p)); + ASSERT_NULL(p); + + p = "/"; + ASSERT_OK(empty_or_root_harder_to_null(&p)); + ASSERT_NULL(p); + + p = "////////"; + ASSERT_OK(empty_or_root_harder_to_null(&p)); + ASSERT_NULL(p); + + p = "/../../././//"; + ASSERT_OK(empty_or_root_harder_to_null(&p)); + ASSERT_NULL(p); + + p = "/usr"; + ASSERT_OK(empty_or_root_harder_to_null(&p)); + ASSERT_STREQ(p, "/usr"); + + p = "/usr/../../../"; + ASSERT_OK(empty_or_root_harder_to_null(&p)); + ASSERT_NULL(p); + + p = "/usr/"; + ASSERT_OK(empty_or_root_harder_to_null(&p)); + ASSERT_STREQ(p, "/usr/"); + + p = "///././/../../usr////"; + ASSERT_OK(empty_or_root_harder_to_null(&p)); + ASSERT_STREQ(p, "///././/../../usr////"); +} + TEST(path_startswith_set) { ASSERT_STREQ(PATH_STARTSWITH_SET("/foo/bar", "/foo/quux", "/foo/bar", "/zzz"), ""); ASSERT_STREQ(PATH_STARTSWITH_SET("/foo/bar", "/foo/quux", "/foo/", "/zzz"), "bar");