chiark / gitweb /
tree-wide: remove Lennart's copyright lines
[elogind.git] / src / basic / alloc-util.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <stdint.h>
4 #include <string.h>
5
6 #include "alloc-util.h"
7 #include "macro.h"
8 #include "util.h"
9
10 void* memdup(const void *p, size_t l) {
11         void *ret;
12
13         assert(l == 0 || p);
14
15         ret = malloc(l);
16         if (!ret)
17                 return NULL;
18
19         memcpy(ret, p, l);
20         return ret;
21 }
22
23 void* memdup_suffix0(const void *p, size_t l) {
24         void *ret;
25
26         assert(l == 0 || p);
27
28         /* The same as memdup() but place a safety NUL byte after the allocated memory */
29
30         ret = malloc(l + 1);
31         if (!ret)
32                 return NULL;
33
34         *((uint8_t*) mempcpy(ret, p, l)) = 0;
35         return ret;
36 }
37
38 void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
39         size_t a, newalloc;
40         void *q;
41
42         assert(p);
43         assert(allocated);
44
45         if (*allocated >= need)
46                 return *p;
47
48         newalloc = MAX(need * 2, 64u / size);
49         a = newalloc * size;
50
51         /* check for overflows */
52         if (a < size * need)
53                 return NULL;
54
55         q = realloc(*p, a);
56         if (!q)
57                 return NULL;
58
59         *p = q;
60         *allocated = newalloc;
61         return q;
62 }
63
64 void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) {
65         size_t prev;
66         uint8_t *q;
67
68         assert(p);
69         assert(allocated);
70
71         prev = *allocated;
72
73         q = greedy_realloc(p, allocated, need, size);
74         if (!q)
75                 return NULL;
76
77         if (*allocated > prev)
78                 memzero(q + prev * size, (*allocated - prev) * size);
79
80         return q;
81 }