summaryrefslogtreecommitdiff
path: root/src/basic/fs-util.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-03-22 19:54:24 +0100
committerSven Eden <yamakuzure@gmx.net>2018-08-24 16:47:08 +0200
commit33da2d049720dfa17bbbbf70200130fd977bfb33 (patch)
tree1acb80e63d443e3e0d048af47a036a2b4d83a489 /src/basic/fs-util.c
parentac1936363db2bf6284d225ab6f221e5e9b25470b (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.c38
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;