summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2023-04-11 12:36:13 +0900
committerGitHub <noreply@github.com>2023-04-11 12:36:13 +0900
commit2653ded4d1c191c671d6aed51821dd976f2c9712 (patch)
tree50b37e8fd357c960fab85fddcaaa1fb01aefb8d4
parent562f22dbfc37d22cb27a3e913cfb27a2db1cb393 (diff)
parentfb4d9bf47fcc647c3b43f0b61c6bcf0424397f03 (diff)
downloadsystemd-2653ded4d1c191c671d6aed51821dd976f2c9712.tar.gz
Merge pull request #27199 from yuwata/find-esp
path-util: introduce path_prefix_root_cwd(), and use it in find_esp() and friends
-rw-r--r--src/basic/path-util.c28
-rw-r--r--src/basic/path-util.h1
-rw-r--r--src/shared/find-esp.c16
-rw-r--r--src/test/test-path-util.c39
4 files changed, 74 insertions, 10 deletions
diff --git a/src/basic/path-util.c b/src/basic/path-util.c
index 0b0f0da760..fa2e26789f 100644
--- a/src/basic/path-util.c
+++ b/src/basic/path-util.c
@@ -100,6 +100,34 @@ int path_make_absolute_cwd(const char *p, char **ret) {
return 0;
}
+int path_prefix_root_cwd(const char *p, const char *root, char **ret) {
+ _cleanup_free_ char *root_abs = NULL;
+ char *c;
+ int r;
+
+ assert(p);
+ assert(ret);
+
+ /* Unlike path_make_absolute(), this always prefixes root path if specified.
+ * The root path is always simplified, but the provided path will not.
+ * This is useful for prefixing the result of chaseat(). */
+
+ if (empty_or_root(root))
+ return path_make_absolute_cwd(p, ret);
+
+ r = path_make_absolute_cwd(root, &root_abs);
+ if (r < 0)
+ return r;
+
+ path_simplify(root_abs);
+ c = path_join(root_abs, p);
+ if (!c)
+ return -ENOMEM;
+
+ *ret = c;
+ return 0;
+}
+
int path_make_relative(const char *from, const char *to, char **ret) {
_cleanup_free_ char *result = NULL;
unsigned n_parents;
diff --git a/src/basic/path-util.h b/src/basic/path-util.h
index 7843599816..a0af9de674 100644
--- a/src/basic/path-util.h
+++ b/src/basic/path-util.h
@@ -60,6 +60,7 @@ int path_split_and_make_absolute(const char *p, char ***ret);
char* path_make_absolute(const char *p, const char *prefix);
int safe_getcwd(char **ret);
int path_make_absolute_cwd(const char *p, char **ret);
+int path_prefix_root_cwd(const char *p, const char *root, char **ret);
int path_make_relative(const char *from, const char *to, char **ret);
int path_make_relative_parent(const char *from_child, const char *to, char **ret);
char *path_startswith_full(const char *path, const char *prefix, bool accept_dot_dot) _pure_;
diff --git a/src/shared/find-esp.c b/src/shared/find-esp.c
index 0d45249d63..6a0002a2bd 100644
--- a/src/shared/find-esp.c
+++ b/src/shared/find-esp.c
@@ -540,11 +540,9 @@ int find_esp_and_warn(
return r;
if (ret_path) {
- char *q = path_join(empty_to_root(root), p);
- if (!q)
- return -ENOMEM;
-
- *ret_path = TAKE_PTR(q);
+ r = path_prefix_root_cwd(p, root, ret_path);
+ if (r < 0)
+ return r;
}
if (ret_part)
*ret_part = part;
@@ -861,11 +859,9 @@ int find_xbootldr_and_warn(
return r;
if (ret_path) {
- char *q = path_join(empty_to_root(root), p);
- if (!q)
- return -ENOMEM;
-
- *ret_path = TAKE_PTR(q);
+ r = path_prefix_root_cwd(p, root, ret_path);
+ if (r < 0)
+ return r;
}
if (ret_uuid)
*ret_uuid = uuid;
diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c
index e40ffea4d5..22e8f3481a 100644
--- a/src/test/test-path-util.c
+++ b/src/test/test-path-util.c
@@ -494,6 +494,45 @@ TEST(fsck_exists) {
assert_se(fsck_exists_for_fstype("/../bin/") == 0);
}
+TEST(path_prefix_root_cwd) {
+ _cleanup_free_ char *cwd = NULL, *ret = NULL, *expected = NULL;
+
+ assert_se(safe_getcwd(&cwd) >= 0);
+
+ assert_se(path_prefix_root_cwd("hoge", NULL, &ret) >= 0);
+ assert_se(expected = path_join(cwd, "hoge"));
+ assert_se(streq(ret, expected));
+
+ ret = mfree(ret);
+ expected = mfree(expected);
+
+ assert_se(path_prefix_root_cwd("/hoge", NULL, &ret) >= 0);
+ assert_se(streq(ret, "/hoge"));
+
+ ret = mfree(ret);
+
+ assert_se(path_prefix_root_cwd("hoge", "/a/b//./c///", &ret) >= 0);
+ assert_se(streq(ret, "/a/b/c/hoge"));
+
+ ret = mfree(ret);
+
+ assert_se(path_prefix_root_cwd("hoge", "a/b//./c///", &ret) >= 0);
+ assert_se(expected = path_join(cwd, "a/b/c/hoge"));
+ assert_se(streq(ret, expected));
+
+ ret = mfree(ret);
+ expected = mfree(expected);
+
+ assert_se(path_prefix_root_cwd("/../hoge/aaa/../././b", "/a/b//./c///", &ret) >= 0);
+ assert_se(streq(ret, "/a/b/c/../hoge/aaa/../././b"));
+
+ ret = mfree(ret);
+
+ assert_se(path_prefix_root_cwd("/../hoge/aaa/../././b", "a/b//./c///", &ret) >= 0);
+ assert_se(expected = path_join(cwd, "a/b/c/../hoge/aaa/../././b"));
+ assert_se(streq(ret, expected));
+}
+
static void test_path_make_relative_one(const char *from, const char *to, const char *expected) {
_cleanup_free_ char *z = NULL;
int r;