diff options
author | Lennart Poettering <lennart@poettering.net> | 2018-03-22 19:54:24 +0100 |
---|---|---|
committer | Sven Eden <yamakuzure@gmx.net> | 2018-08-24 16:47:08 +0200 |
commit | 33da2d049720dfa17bbbbf70200130fd977bfb33 (patch) | |
tree | 1acb80e63d443e3e0d048af47a036a2b4d83a489 /src/basic/fs-util.c | |
parent | ac1936363db2bf6284d225ab6f221e5e9b25470b (diff) |
fs-util: add new CHASE_TRAIL_SLASH flag for chase_symlinks()
This rearranges chase_symlinks() a bit: if no special flags are
specified it will now revert to behaviour before
b12d25a8d631af00b200e7aa9dbba6ba4a4a59ff. However, if the new
CHASE_TRAIL_SLASH flag is specified it will follow the behaviour
introduced by that commit.
I wasn't sure which one to make the beaviour that requires specification
of a flag to enable. I opted to make the "append trailing slash"
behaviour the one to enable by a flag, following the thinking that the
function should primarily be used to generate a normalized path, and I
am pretty sure a path without trailing slash is the more "normalized"
one, as the trailing slash is not really a part of it, but merely a
"decorator" that tells various system calls to generate ENOTDIR if the
path doesn't refer to a path.
Or to say this differently: if the slash was part of normalization then
we really should add it in all cases when the final path is a directory,
not just when the user originally specified it.
Fixes: #8544
Replaces: #8545
Diffstat (limited to 'src/basic/fs-util.c')
-rw-r--r-- | src/basic/fs-util.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index 12255fe0c..8617968c1 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -469,8 +469,10 @@ int get_files_in_directory(const char *path, char ***list) { n++; } - if (list) - *list = TAKE_PTR(l); + if (list) { + *list = l; + l = NULL; /* avoid freeing */ + } return n; } @@ -698,8 +700,10 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, /* Just a single slash? Then we reached the end. */ if (path_equal(first, "/")) { /* Preserve the trailing slash */ - if (!strextend(&done, "/", NULL)) - return -ENOMEM; + + if (flags & CHASE_TRAIL_SLASH) + if (!strextend(&done, "/", NULL)) + return -ENOMEM; break; } @@ -745,7 +749,8 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, } safe_close(fd); - fd = TAKE_FD(fd_parent); + fd = fd_parent; + fd_parent = -1; continue; } @@ -850,9 +855,10 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, } /* If this is not a symlink, then let's just add the name we read to what we already verified. */ - if (!done) - done = TAKE_PTR(first); - else { + if (!done) { + done = first; + first = NULL; + } else { /* If done is "/", as first also contains slash at the head, then remove this redundant slash. */ if (streq(done, "/")) *done = '\0'; @@ -863,7 +869,8 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, /* And iterate again, but go one directory further down. */ safe_close(fd); - fd = TAKE_FD(child); + fd = child; + child = -1; } if (!done) { @@ -873,15 +880,22 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, return -ENOMEM; } - if (ret) - *ret = TAKE_PTR(done); + if (ret) { + *ret = done; + done = NULL; + } if (flags & CHASE_OPEN) { + int q; + /* Return the O_PATH fd we currently are looking to the caller. It can translate it to a proper fd by * opening /proc/self/fd/xyz. */ assert(fd >= 0); - return TAKE_FD(fd); + q = fd; + fd = -1; + + return q; } return exists; |