]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/basic/alloc-util.h
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / basic / alloc-util.h
index f5097ea117538750f48f222e3d793a51938b55dd..38d1546b551fcca6d38d2037e12f8a22e098d296 100644 (file)
@@ -1,5 +1,4 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
+/* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
 /***
@@ -38,6 +37,8 @@
 
 #define newdup(t, p, n) ((t*) memdup_multiply(p, sizeof(t), (n)))
 
+#define newdup_suffix0(t, p, n) ((t*) memdup_suffix0_multiply(p, sizeof(t), (n)))
+
 #define malloc0(n) (calloc(1, (n)))
 
 static inline void *mfree(void *memory) {
@@ -45,7 +46,16 @@ 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);
+void* memdup_suffix0(const void*p, size_t l) _alloc_(2);
 
 static inline void freep(void *p) {
         free(*(void**) p);
@@ -53,25 +63,36 @@ static inline void freep(void *p) {
 
 #define _cleanup_free_ _cleanup_(freep)
 
-_malloc_  _alloc_(1, 2) static inline void *malloc_multiply(size_t a, size_t b) {
-        if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
+static inline bool size_multiply_overflow(size_t size, size_t need) {
+        return _unlikely_(need != 0 && size > (SIZE_MAX / need));
+}
+
+_malloc_  _alloc_(1, 2) static inline void *malloc_multiply(size_t size, size_t need) {
+        if (size_multiply_overflow(size, need))
+                return NULL;
+
+        return malloc(size * need);
+}
+
+_alloc_(2, 3) static inline void *realloc_multiply(void *p, size_t size, size_t need) {
+        if (size_multiply_overflow(size, need))
                 return NULL;
 
-        return malloc(a * b);
+        return realloc(p, size * need);
 }
 
-_alloc_(2, 3) static inline void *realloc_multiply(void *p, size_t a, size_t b) {
-        if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
+_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t size, size_t need) {
+        if (size_multiply_overflow(size, need))
                 return NULL;
 
-        return realloc(p, a * b);
+        return memdup(p, size * need);
 }
 
-_alloc_(2, 3) static inline void *memdup_multiply(const void *p, size_t a, size_t b) {
-        if (_unlikely_(b != 0 && a > ((size_t) -1) / b))
+_alloc_(2, 3) static inline void *memdup_suffix0_multiply(const void *p, size_t size, size_t need) {
+        if (size_multiply_overflow(size, need))
                 return NULL;
 
-        return memdup(p, a * b);
+        return memdup_suffix0(p, size * need);
 }
 
 void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size);