diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/chase-symlinks.c | 23 |
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); } |