chiark / gitweb /
tree-wide: introduce free_and_replace helper
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 16 Oct 2016 23:23:35 +0000 (19:23 -0400)
committerSven Eden <yamakuzure@gmx.net>
Wed, 5 Jul 2017 06:50:55 +0000 (08:50 +0200)
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 [new file with mode: 0644]
src/basic/alloc-util.h
src/basic/fs-util.c
src/basic/path-util.c

diff --git a/coccinelle/free_and_replace.cocci b/coccinelle/free_and_replace.cocci
new file mode 100644 (file)
index 0000000..9dcdbf4
--- /dev/null
@@ -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);
index ceeee519b79f864ccbf359fede0c91c3364c7e36..a44dd473c1106574472ae2cd84e7db7f2df935ae 100644 (file)
@@ -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) {
index 60925f2ac130e63581b200e46f24f72a6c21e12b..55f606cebc23d223150d44d427dd82c9dad83754 100644 (file)
@@ -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);
index 3af2bd0fd4ab82aeb5ede0d7fbd8274f2a9285d2..cdbb2d39815f349fd4736fcb05e639126935a312 100644 (file)
@@ -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);