summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/basic/chase-symlinks.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/src/basic/chase-symlinks.c b/src/basic/chase-symlinks.c
index 46e4e7ed7a..bab5a5b286 100644
--- a/src/basic/chase-symlinks.c
+++ b/src/basic/chase-symlinks.c
@@ -215,7 +215,7 @@ int chase_symlinks_at(
return -errno;
if (flags & CHASE_TRAIL_SLASH)
- append_trail_slash = endswith(buffer, "/") || endswith(buffer, "/.");
+ append_trail_slash = ENDSWITH_SET(buffer, "/", "/.");
for (todo = buffer;;) {
_cleanup_free_ char *first = NULL;
@@ -380,8 +380,15 @@ int chase_symlinks_at(
close_and_replace(fd, child);
}
- if (ret_path)
+ if (ret_path) {
+ if (!done) {
+ done = strdup(append_trail_slash ? "./" : ".");
+ if (!done)
+ return -ENOMEM;
+ }
+
*ret_path = TAKE_PTR(done);
+ }
if (ret_fd) {
/* Return the O_PATH fd we currently are looking to the caller. It can translate it to a
@@ -400,6 +407,12 @@ chased_one:
if (ret_path) {
const char *e;
+ if (!done) {
+ done = strdup(append_trail_slash ? "./" : ".");
+ if (!done)
+ return -ENOMEM;
+ }
+
/* todo may contain slashes at the beginning. */
r = path_find_first_component(&todo, /* accept_dot_dot= */ true, &e);
if (r < 0)
@@ -489,6 +502,12 @@ int chase_symlinks(
if (!q)
return -ENOMEM;
+ path_simplify(q);
+
+ if (FLAGS_SET(flags, CHASE_TRAIL_SLASH) && ENDSWITH_SET(path, "/", "/."))
+ if (!strextend(&q, "/"))
+ return -ENOMEM;
+
*ret_path = TAKE_PTR(q);
}