macro: introduce TAKE_PTR() macro

This macro will read a pointer of any type, return it, and set the
pointer to NULL. This is useful as an explicit concept of passing
ownership of a memory area between pointers.

This takes inspiration from Rust:

https://doc.rust-lang.org/std/option/enum.Option.html#method.take

and was suggested by Alan Jenkins (@sourcejedi).

It drops ~160 lines of code from our codebase, which makes me like it.
Also, I think it clarifies passing of ownership, and thus helps
readability a bit (at least for the initiated who know the new macro)
This commit is contained in:
Lennart Poettering
2018-03-22 20:21:42 +01:00
parent 1147eef0b6
commit ae2a15bc14
93 changed files with 215 additions and 379 deletions
+7 -12
View File
@@ -458,10 +458,8 @@ int get_files_in_directory(const char *path, char ***list) {
n++;
}
if (list) {
*list = l;
l = NULL; /* avoid freeing */
}
if (list)
*list = TAKE_PTR(l);
return n;
}
@@ -838,10 +836,9 @@ 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 = first;
first = NULL;
} else {
if (!done)
done = TAKE_PTR(first);
else {
/* If done is "/", as first also contains slash at the head, then remove this redundant slash. */
if (streq(done, "/"))
*done = '\0';
@@ -863,10 +860,8 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
return -ENOMEM;
}
if (ret) {
*ret = done;
done = NULL;
}
if (ret)
*ret = TAKE_PTR(done);
if (flags & CHASE_OPEN) {
int q;