The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
talloc.h
Go to the documentation of this file.
1#pragma once
2/*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16 */
17
18/** Functions which we wish were included in the standard talloc distribution
19 *
20 * @file src/lib/util/talloc.h
21 *
22 * @copyright 2017 The FreeRADIUS server project
23 * @copyright 2017 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
24 */
25RCSIDH(talloc_h, "$Id: 5671361c5430390cfee2378bb658ab56c569b211 $")
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31#include <ctype.h>
32#include <stdbool.h>
33#include <stdint.h>
34
35#ifdef HAVE_WDOCUMENTATION
36DIAG_OFF(documentation)
37#endif
38#include <talloc.h>
39#ifdef HAVE_WDOCUMENTATION
40DIAG_ON(documentation)
41#endif
42
43#include <freeradius-devel/autoconf.h> /* Very easy to miss including in special builds */
44#include <freeradius-devel/build.h>
45#include <freeradius-devel/missing.h>
46#include <freeradius-devel/util/sbuff.h>
47
48#undef talloc_autofree_context
49/** The original function is deprecated, so replace it with our version
50 */
51#define talloc_autofree_context talloc_autofree_context_global
52
53/** Iterate over a talloced array of elements
54 *
55@verbatim
56talloc_foreach(vpt_m, vpt) {
57 tmpl_debug(vpt);
58}
59@endverbatim
60 *
61 * There seems to be a limitation in for loop initialiser arguments where they all
62 * must be the same type, though we can control the number of layers of pointer
63 * indirection on a per variable basis.
64 *
65 * We declare _p to be a pointer of the specified _type, and initialise it to the
66 * start of the array. We declare _end to be a pointer of the specified type and
67 * initialise it to point to the end of the array using talloc_array_length().
68 *
69 * _iter is only updated in the condition to avoid de-referencing invalid memory.
70 *
71 * @param[in] _array to iterate over. May contain zero elements.
72 * @param[in] _iter Name of iteration variable.
73 * Will be declared in the scope of the loop.
74 */
75#define talloc_foreach(_array, _iter) \
76 for (__typeof__(_array[0]) _iter, *_p = (void *)(_array), *_end = _array ? (void *)((_array) + talloc_array_length(_array)) : NULL; \
77 (_p < _end) && (_iter = *((void **)(uintptr_t)(_p))); \
78 _p = (__typeof__(_p))((__typeof__(_array))_p) + 1)
79
80typedef int(* fr_talloc_free_func_t)(void *fire_ctx, void *uctx);
81
84
85/** Structure to record a destructor operation on a specific talloc chunk
86 *
87 * Provided here so that additional memory can be allocated with talloc pool.
88 */
90 void *fire; //!< Parent chunk.
91
92 fr_talloc_free_func_t func; //!< Free function.
93 void *uctx; //!< uctx to pass to free function.
94 fr_talloc_destructor_disarm_t *ds; //!< Chunk to free.
95};
96
97/** Structure to record a destructor to disarm if a child talloc chunk is freed
98 *
99 * Provided here so that additional memory can be allocated with talloc pool.
100 */
102 fr_talloc_destructor_t *d; //!< Destructor to disarm.
103};
104
105/** Allocate a top level chunk with a constant name
106 *
107 * @param[in] name Must be a string literal.
108 * @return
109 * - NULL on allocation error.
110 * - A new talloc chunk on success.
111 */
112static inline TALLOC_CTX *talloc_init_const(char const *name)
113{
114 TALLOC_CTX *ctx;
115
116 ctx = talloc_new(NULL);
117 if (unlikely(!ctx)) return NULL;
118
119 talloc_set_name_const(ctx, name);
120
121 return ctx;
122}
123
124/** Convert a talloced string to lowercase
125 *
126 * @param[in] str to convert.
127 */
128static inline void talloc_bstr_tolower(char *str)
129{
130 char *p, *q;
131
132 for (p = str, q = p + (talloc_array_length(str) - 1); p < q; p++) *p = tolower((uint8_t) *p);
133}
134
135void talloc_free_data(void *data);
136
137void *talloc_null_ctx(void);
138
139fr_talloc_destructor_t *talloc_destructor_add(TALLOC_CTX *fire_ctx, TALLOC_CTX *disarm_ctx,
140 fr_talloc_free_func_t func, void const *uctx);
141
143
144int talloc_link_ctx(TALLOC_CTX *parent, TALLOC_CTX *child);
145
147TALLOC_CTX *talloc_page_aligned_pool(TALLOC_CTX *ctx, void **start, size_t *end_len, unsigned int headers, size_t size);
148TALLOC_CTX *talloc_aligned_array(TALLOC_CTX *ctx, void **start, size_t alignment, size_t size);
149
150/*
151 * Add variant that zeroes out newly allocated memory
152 */
153#if defined(HAVE__TALLOC_POOLED_OBJECT) && defined(talloc_pooled_object)
154# define HAVE_TALLOC_ZERO_POOLED_OBJECT 1
155# define HAVE_TALLOC_POOLED_OBJECT 1
156
157# define talloc_zero_pooled_object(_ctx, _type, _num_subobjects, _total_subobjects_size) \
158 (_type *)_talloc_zero_pooled_object((_ctx), sizeof(_type), #_type, \
159 (_num_subobjects), (_total_subobjects_size))
160
161static inline TALLOC_CTX *_talloc_zero_pooled_object(const void *ctx,
162 size_t type_size,
163 const char *type_name,
164 unsigned num_subobjects,
165 size_t total_subobjects_size)
166{
167 TALLOC_CTX *new;
168 new = _talloc_pooled_object(ctx, type_size, type_name, num_subobjects, total_subobjects_size);
169 if (unlikely(!new)) return NULL;
170 memset(new, 0, type_size);
171 return new;
172}
173/*
174 * Fall back to non-pooled variants
175 */
176#else
177# define talloc_zero_pooled_object(_ctx, _type, _num_subobjects, _total_subobjects_size) \
178 talloc_zero(_ctx, _type)
179#undef talloc_pooled_object
180# define talloc_pooled_object(_ctx, _type, _num_subobjects, _total_subobjects_size) \
181 talloc(_ctx, _type)
182#endif
183
184/** @hidecallergraph */
185char *talloc_typed_strdup(TALLOC_CTX *ctx, char const *p);
186
187char *talloc_typed_strdup_buffer(TALLOC_CTX *ctx, char const *p);
188
189char *talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt, ...) CC_HINT(format (printf, 2, 3));
190
191char *talloc_typed_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap) CC_HINT(format (printf, 2, 0)) CC_HINT(nonnull (2));
192
193uint8_t *talloc_typed_memdup(TALLOC_CTX *ctx, uint8_t const *in, size_t inlen);
194
195char *talloc_bstrdup(TALLOC_CTX *ctx, char const *in);
196
197char *talloc_bstrndup(TALLOC_CTX *ctx, char const *in, size_t inlen);
198
199char *talloc_bstr_append(TALLOC_CTX *ctx, char *to, char const *from, size_t from_len);
200
201char *talloc_bstr_realloc(TALLOC_CTX *ctx, char *in, size_t inlen);
202
203char *talloc_buffer_append_buffer(TALLOC_CTX *ctx, char *to, char const *from);
204
205char *talloc_buffer_append_variadic_buffer(TALLOC_CTX *ctx, char *to, int argc, ...);
206
207int talloc_memcmp_array(uint8_t const *a, uint8_t const *b);
208
209int talloc_memcmp_bstr(char const *a, char const *b);
210
211int talloc_decrease_ref_count(void const *ptr);
212
213void **talloc_array_null_terminate(void **array);
214
215void **talloc_array_null_strip(void **array);
216
217fr_slen_t talloc_array_concat(fr_sbuff_t *out, char const * const *array, char const *sep);
218
219
220/** Free const'd memory
221 *
222 * @param[in] ptr to free.
223 */
224static inline int talloc_const_free(void const *ptr)
225{
226 if (!ptr) return 0;
227
228 return talloc_free(UNCONST(void *, ptr));
229}
230
231/** Free a list of talloced structures containing a next field
232 *
233 * @param[in] _head of list to free. Will set memory it points to to be NULL.
234 */
235#define talloc_list_free(_head) _talloc_list_free((void **)_head, offsetof(__typeof__(**(_head)), next))
236
237static inline void _talloc_list_free(void **head, size_t offset)
238{
239 void *v = *head, *n;
240
241 while (v) {
242 n = *((void **)(((uint8_t *)(v)) + offset));
243 talloc_free(v);
244 v = n;
245 }
246 *head = NULL;
247}
248
249/** Verify a list of talloced structures are the correct type and are still valid
250 *
251 * @param[in] _head of list to check.
252 * @param[in] _type of talloced chunk we expect.
253 */
254#ifndef TALLOC_GET_TYPE_ABORT_NOOP
255# define talloc_list_get_type_abort(_head, _type) (_type *)_talloc_list_get_type_abort(_head, offsetof(__typeof__(*(_head)), next), #_type, __location__)
256static inline void *_talloc_list_get_type_abort(void *head, size_t offset, char const *type, char const *location)
257{
258 void *v = head, *n;
259
260 if (!v) _talloc_get_type_abort(v, type, location); /* Behave like the normal talloc_get_type_abort function */
261
262 while (v) {
263 n = *((void **)(((uint8_t *)(v)) + offset));
264 _talloc_get_type_abort(v, type, location);
265 v = n;
266 }
267
268 return head;
269}
270#else
271# define talloc_list_get_type_abort(_head, _type) (_type *)(_head)
272#endif
273
274/*
275 * talloc portability issues. 'const' is not part of the talloc
276 * type, but it is part of the pointer type. But only if
277 * talloc_get_type_abort() is just a cast.
278 */
279#ifdef TALLOC_GET_TYPE_ABORT_NOOP
280# define talloc_get_type_abort_const(ptr, type) (const type *)(ptr)
281#else
282# define talloc_get_type_abort_const talloc_get_type_abort
283#endif
284
285/** Returns the length of a talloc array containing a string
286 *
287 * @param[in] s to return the length of.
288 */
289static inline size_t talloc_strlen(char const *s)
290{
291 char const *our_s = talloc_get_type_abort_const(s, char);
292 return talloc_array_length(our_s) - 1;
293}
294
295TALLOC_CTX *talloc_autofree_context_global(void);
297
299
302
303#ifdef __cplusplus
304}
305#endif
int n
Definition acutest.h:577
static int const char * fmt
Definition acutest.h:573
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition build.h:167
#define DIAG_ON(_x)
Definition build.h:458
#define RCSIDH(h, id)
Definition build.h:484
#define unlikely(_x)
Definition build.h:381
#define DIAG_OFF(_x)
Definition build.h:457
static fr_slen_t in
Definition dict.h:824
talloc_free(reap)
long int ssize_t
unsigned char uint8_t
ssize_t fr_slen_t
static char const * name
fr_aka_sim_id_type_t type
Functions which we wish were included in the standard talloc distribution.
void ** talloc_array_null_terminate(void **array)
Add a NULL pointer to an array of pointers.
Definition talloc.c:852
char * talloc_bstrdup(TALLOC_CTX *ctx, char const *in)
Binary safe strdup function.
Definition talloc.c:536
#define talloc_get_type_abort_const
Definition talloc.h:282
TALLOC_CHILD_CTX * talloc_child_ctx_alloc(TALLOC_CHILD_CTX *parent)
Allocate a TALLOC_CHILD_CTX from a parent.
Definition talloc.c:1052
static int talloc_const_free(void const *ptr)
Free const'd memory.
Definition talloc.h:224
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...))
Call talloc vasprintf, setting the type on the new chunk correctly.
Definition talloc.c:492
fr_talloc_destructor_t * talloc_destructor_add(TALLOC_CTX *fire_ctx, TALLOC_CTX *disarm_ctx, fr_talloc_free_func_t func, void const *uctx)
Add an additional destructor to a talloc chunk.
Definition talloc.c:100
char * talloc_typed_strdup_buffer(TALLOC_CTX *ctx, char const *p)
Call talloc_strndup, setting the type on the new chunk correctly.
Definition talloc.c:469
fr_slen_t talloc_array_concat(fr_sbuff_t *out, char const *const *array, char const *sep)
Concat an array of strings (not NULL terminated), with a string separator.
Definition talloc.c:914
static void * _talloc_list_get_type_abort(void *head, size_t offset, char const *type, char const *location)
Definition talloc.h:256
ssize_t talloc_hdr_size(void)
Calculate the size of the talloc chunk header.
Definition talloc.c:275
TALLOC_CTX * talloc_autofree_context_global(void)
Definition talloc.c:957
TALLOC_CHILD_CTX * talloc_child_ctx_init(TALLOC_CTX *ctx)
Allocate and initialize a TALLOC_CHILD_CTX.
Definition talloc.c:1038
int talloc_memcmp_array(uint8_t const *a, uint8_t const *b)
Compares two talloced uint8_t arrays with memcmp.
Definition talloc.c:772
char * talloc_buffer_append_variadic_buffer(TALLOC_CTX *ctx, char *to, int argc,...)
Concatenate to + ...
Definition talloc.c:696
char * talloc_bstr_realloc(TALLOC_CTX *ctx, char *in, size_t inlen)
Trim a bstr (char) buffer.
Definition talloc.c:628
fr_talloc_free_func_t func
Free function.
Definition talloc.h:92
static TALLOC_CTX * talloc_init_const(char const *name)
Allocate a top level chunk with a constant name.
Definition talloc.h:112
TALLOC_CTX * talloc_aligned_array(TALLOC_CTX *ctx, void **start, size_t alignment, size_t size)
Return a page aligned talloc memory array.
Definition talloc.c:200
static void _talloc_list_free(void **head, size_t offset)
Definition talloc.h:237
int talloc_link_ctx(TALLOC_CTX *parent, TALLOC_CTX *child)
Link two different parent and child contexts, so the child is freed before the parent.
Definition talloc.c:171
uint8_t * talloc_typed_memdup(TALLOC_CTX *ctx, uint8_t const *in, size_t inlen)
Call talloc_memdup, setting the type on the new chunk correctly.
Definition talloc.c:420
char * talloc_bstrndup(TALLOC_CTX *ctx, char const *in, size_t inlen)
Binary safe strndup function.
Definition talloc.c:564
void * talloc_null_ctx(void)
Retrieve the current talloc NULL ctx.
Definition talloc.c:53
fr_talloc_destructor_t * d
Destructor to disarm.
Definition talloc.h:102
TALLOC_CTX * talloc_page_aligned_pool(TALLOC_CTX *ctx, void **start, size_t *end_len, unsigned int headers, size_t size)
Return a page aligned talloc memory pool.
Definition talloc.c:312
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
Definition talloc.c:445
void talloc_free_data(void *data)
A wrapper that can be passed to tree or hash alloc functions that take a fr_free_t.
Definition talloc.c:41
int talloc_decrease_ref_count(void const *ptr)
Decrease the reference count on a ptr.
Definition talloc.c:820
TALLOC_CTX * talloc_autofree_context_thread_local(void)
Get a thread-safe autofreed ctx that will be freed when the thread or process exits.
Definition talloc.c:988
void * uctx
uctx to pass to free function.
Definition talloc.h:93
char * talloc_buffer_append_buffer(TALLOC_CTX *ctx, char *to, char const *from)
Concatenate to + from.
Definition talloc.c:660
void ** talloc_array_null_strip(void **array)
Remove a NULL termination pointer from an array of pointers.
Definition talloc.c:882
char * talloc_bstr_append(TALLOC_CTX *ctx, char *to, char const *from, size_t from_len)
Append a bstr to a bstr.
Definition talloc.c:592
void * fire
Parent chunk.
Definition talloc.h:90
void talloc_destructor_disarm(fr_talloc_destructor_t *d)
Disarm a destructor and free all memory allocated in the trigger ctxs.
Definition talloc.c:142
int(* fr_talloc_free_func_t)(void *fire_ctx, void *uctx)
Definition talloc.h:80
static void talloc_bstr_tolower(char *str)
Convert a talloced string to lowercase.
Definition talloc.h:128
fr_talloc_destructor_disarm_t * ds
Chunk to free.
Definition talloc.h:94
static size_t talloc_strlen(char const *s)
Returns the length of a talloc array containing a string.
Definition talloc.h:289
char * talloc_typed_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap))
Call talloc vasprintf, setting the type on the new chunk correctly.
Definition talloc.c:519
int talloc_memcmp_bstr(char const *a, char const *b)
Compares two talloced char arrays with memcmp.
Definition talloc.c:796
Structure to record a destructor to disarm if a child talloc chunk is freed.
Definition talloc.h:101
Structure to record a destructor operation on a specific talloc chunk.
Definition talloc.h:89
static fr_slen_t head
Definition xlat.h:422
static fr_slen_t parent
Definition pair.h:851
static fr_slen_t data
Definition value.h:1265
static size_t char fr_sbuff_t size_t inlen
Definition value.h:997
int nonnull(2, 5))
static size_t char ** out
Definition value.h:997