From a0db25e25b5691e4fc0afa5f5a9a8d1ce586decf Mon Sep 17 00:00:00 2001 From: =?utf8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 16 Oct 2016 19:23:35 -0400 Subject: [PATCH] tree-wide: introduce free_and_replace helper It's a common pattern, so add a helper for it. A macro is necessary because a function that takes a pointer to a pointer would be type specific, similarly to cleanup functions. Seems better to use a macro. --- coccinelle/free_and_replace.cocci | 15 +++++++++++++++ src/basic/alloc-util.h | 8 ++++++++ src/basic/fs-util.c | 8 ++------ src/basic/path-util.c | 4 +--- 4 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 coccinelle/free_and_replace.cocci diff --git a/coccinelle/free_and_replace.cocci b/coccinelle/free_and_replace.cocci new file mode 100644 index 000000000..9dcdbf4d4 --- /dev/null +++ b/coccinelle/free_and_replace.cocci @@ -0,0 +1,15 @@ +@@ +expression p, q; +@@ +- free(p); +- p = q; +- q = NULL; +- return 0; ++ return free_and_replace(p, q); +@@ +expression p, q; +@@ +- free(p); +- p = q; +- q = NULL; ++ free_and_replace(p, q); diff --git a/src/basic/alloc-util.h b/src/basic/alloc-util.h index ceeee519b..a44dd473c 100644 --- a/src/basic/alloc-util.h +++ b/src/basic/alloc-util.h @@ -43,6 +43,14 @@ static inline void *mfree(void *memory) { return NULL; } +#define free_and_replace(a, b) \ + ({ \ + free(a); \ + (a) = (b); \ + (b) = NULL; \ + 0; \ + }) + void* memdup(const void *p, size_t l) _alloc_(2); static inline void freep(void *p) { diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index 60925f2ac..55f606ceb 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -684,9 +684,7 @@ int chase_symlinks(const char *path, const char *_root, char **ret) { !path_startswith(parent, root)) return -EINVAL; - free(done); - done = parent; - parent = NULL; + free_and_replace(done, parent); fd_parent = openat(fd, "..", O_CLOEXEC|O_NOFOLLOW|O_PATH); if (fd_parent < 0) @@ -730,9 +728,7 @@ int chase_symlinks(const char *path, const char *_root, char **ret) { if (fd < 0) return -errno; - free(buffer); - buffer = destination; - destination = NULL; + free_and_replace(buffer, destination); todo = buffer; free(done); diff --git a/src/basic/path-util.c b/src/basic/path-util.c index 3af2bd0fd..cdbb2d398 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -290,9 +290,7 @@ char **path_strv_resolve(char **l, const char *prefix) { } else { /* canonicalized path goes outside of * prefix, keep the original path instead */ - free(u); - u = orig; - orig = NULL; + free_and_replace(u, orig); } } else free(t); -- 2.30.2