]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/alloc-util.c
58b70dede4b01b4bec30233dd75e4c73c3421ff9
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
5 #include "alloc-util.h"
7 void* memdup(const void *p
, size_t l
) {
16 return memcpy_safe(ret
, p
, l
);
19 void* memdup_suffix0(const void *p
, size_t l
) {
24 /* The same as memdup() but place a safety NUL byte after the allocated memory */
26 if (_unlikely_(l
== SIZE_MAX
)) /* prevent overflow */
33 ((uint8_t*) ret
)[l
] = 0;
34 return memcpy_safe(ret
, p
, l
);
47 /* We use malloc_usable_size() for determining the current allocated size. On all systems we care
48 * about this should be safe to rely on. Should there ever arise the need to avoid relying on this we
49 * can instead locally fall back to realloc() on every call, rounded up to the next exponent of 2 or
52 if (*p
&& (size
== 0 || (MALLOC_SIZEOF_SAFE(*p
) / size
>= need
)))
55 if (_unlikely_(need
> SIZE_MAX
/2)) /* Overflow check */
59 if (!MUL_ASSIGN_SAFE(&newalloc
, size
))
62 if (newalloc
< 64) /* Allocate at least 64 bytes */
65 q
= realloc(*p
, newalloc
);
72 void* greedy_realloc0(
82 before
= MALLOC_SIZEOF_SAFE(*p
); /* malloc_usable_size() will return 0 on NULL input, as per docs */
84 q
= greedy_realloc(p
, need
, size
);
88 after
= MALLOC_SIZEOF_SAFE(q
);
90 if (size
== 0) /* avoid division by zero */
93 before
= (before
/ size
) * size
; /* Round down */
96 memzero(q
+ before
, after
- before
);
101 void* greedy_realloc_append(
112 assert(from
|| n_from
== 0);
114 if (n_from
> SIZE_MAX
- *n_p
)
117 q
= greedy_realloc(p
, *n_p
+ n_from
, size
);
121 memcpy_safe(q
+ *n_p
* size
, from
, n_from
* size
);
128 void *expand_to_usable(void *ptr
, size_t newsize _unused_
) {
132 size_t malloc_sizeof_safe(void **xp
) {
133 if (_unlikely_(!xp
|| !*xp
))
136 size_t sz
= malloc_usable_size(*xp
);
137 *xp
= expand_to_usable(*xp
, sz
);
138 /* GCC doesn't see the _returns_nonnull_ when built with ubsan, so yet another hint to make it doubly
139 * clear that expand_to_usable won't return NULL.
140 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79265 */
142 assert_not_reached();