The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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  */
25 RCSIDH(talloc_h, "$Id: 1d7cc13b2df104e1dda30f82c3a15c5816e72fc9 $")
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 #include <ctype.h>
32 #include <stdbool.h>
33 #include <stdint.h>
34 
35 #ifdef HAVE_WDOCUMENTATION
36 DIAG_OFF(documentation)
37 #endif
38 #include <talloc.h>
39 #ifdef HAVE_WDOCUMENTATION
40 DIAG_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
56 talloc_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 
80 typedef 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  */
112 static 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 void talloc_free_data(void *data);
125 
126 void *talloc_null_ctx(void);
127 
128 fr_talloc_destructor_t *talloc_destructor_add(TALLOC_CTX *fire_ctx, TALLOC_CTX *disarm_ctx,
129  fr_talloc_free_func_t func, void const *uctx);
130 
132 
133 int talloc_link_ctx(TALLOC_CTX *parent, TALLOC_CTX *child);
134 
135 TALLOC_CTX *talloc_page_aligned_pool(TALLOC_CTX *ctx, void **start, void **end, size_t size);
136 TALLOC_CTX *talloc_aligned_array(TALLOC_CTX *ctx, void **start, size_t alignment, size_t size);
137 
138 /*
139  * Add variant that zeroes out newly allocated memory
140  */
141 #if defined(HAVE__TALLOC_POOLED_OBJECT) && defined(talloc_pooled_object)
142 # define HAVE_TALLOC_ZERO_POOLED_OBJECT 1
143 # define HAVE_TALLOC_POOLED_OBJECT 1
144 
145 # define talloc_zero_pooled_object(_ctx, _type, _num_subobjects, _total_subobjects_size) \
146  (_type *)_talloc_zero_pooled_object((_ctx), sizeof(_type), #_type, \
147  (_num_subobjects), (_total_subobjects_size))
148 
149 static inline TALLOC_CTX *_talloc_zero_pooled_object(const void *ctx,
150  size_t type_size,
151  const char *type_name,
152  unsigned num_subobjects,
153  size_t total_subobjects_size)
154 {
155  TALLOC_CTX *new;
156  new = _talloc_pooled_object(ctx, type_size, type_name, num_subobjects, total_subobjects_size);
157  if (unlikely(!new)) return NULL;
158  memset(new, 0, type_size);
159  return new;
160 }
161 /*
162  * Fall back to non-pooled variants
163  */
164 #else
165 # define talloc_zero_pooled_object(_ctx, _type, _num_subobjects, _total_subobjects_size) \
166  talloc_zero(_ctx, _type)
167 #undef talloc_pooled_object
168 # define talloc_pooled_object(_ctx, _type, _num_subobjects, _total_subobjects_size) \
169  talloc(_ctx, _type)
170 #endif
171 
172 /** @hidecallergraph */
173 char *talloc_typed_strdup(TALLOC_CTX *ctx, char const *p);
174 
175 char *talloc_typed_strdup_buffer(TALLOC_CTX *ctx, char const *p);
176 
177 char *talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt, ...) CC_HINT(format (printf, 2, 3));
178 
179 char *talloc_typed_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap) CC_HINT(format (printf, 2, 0)) CC_HINT(nonnull (2));
180 
181 uint8_t *talloc_typed_memdup(TALLOC_CTX *ctx, uint8_t const *in, size_t inlen);
182 
183 char *talloc_bstrdup(TALLOC_CTX *ctx, char const *in);
184 
185 char *talloc_bstrndup(TALLOC_CTX *ctx, char const *in, size_t inlen);
186 
187 char *talloc_bstr_append(TALLOC_CTX *ctx, char *to, char const *from, size_t from_len);
188 
189 char *talloc_bstr_realloc(TALLOC_CTX *ctx, char *in, size_t inlen);
190 
191 char *talloc_buffer_append_buffer(TALLOC_CTX *ctx, char *to, char const *from);
192 
193 char *talloc_buffer_append_variadic_buffer(TALLOC_CTX *ctx, char *to, int argc, ...);
194 
195 int talloc_memcmp_array(uint8_t const *a, uint8_t const *b);
196 
197 int talloc_memcmp_bstr(char const *a, char const *b);
198 
199 int talloc_decrease_ref_count(void const *ptr);
200 
201 void **talloc_array_null_terminate(void **array);
202 
203 void **talloc_array_null_strip(void **array);
204 
205 fr_slen_t talloc_array_concat(fr_sbuff_t *out, char const * const *array, char const *sep);
206 
207 
208 /** Free const'd memory
209  *
210  * @param[in] ptr to free.
211  */
212 static inline int talloc_const_free(void const *ptr)
213 {
214  if (!ptr) return 0;
215 
216  return talloc_free(UNCONST(void *, ptr));
217 }
218 
219 /** Free a list of talloced structures containing a next field
220  *
221  * @param[in] _head of list to free. Will set memory it points to to be NULL.
222  */
223 #define talloc_list_free(_head) _talloc_list_free((void **)_head, offsetof(__typeof__(**(_head)), next))
224 
225 static inline void _talloc_list_free(void **head, size_t offset)
226 {
227  void *v = *head, *n;
228 
229  while (v) {
230  n = *((void **)(((uint8_t *)(v)) + offset));
231  talloc_free(v);
232  v = n;
233  }
234  *head = NULL;
235 }
236 
237 /** Verify a list of talloced structures are the correct type and are still valid
238  *
239  * @param[in] _head of list to check.
240  * @param[in] _type of talloced chunk we expect.
241  */
242 #ifndef TALLOC_GET_TYPE_ABORT_NOOP
243 # define talloc_list_get_type_abort(_head, _type) (_type *)_talloc_list_get_type_abort(_head, offsetof(__typeof__(*(_head)), next), #_type, __location__)
244 static inline void *_talloc_list_get_type_abort(void *head, size_t offset, char const *type, char const *location)
245 {
246  void *v = head, *n;
247 
248  if (!v) _talloc_get_type_abort(v, type, location); /* Behave like the normal talloc_get_type_abort function */
249 
250  while (v) {
251  n = *((void **)(((uint8_t *)(v)) + offset));
252  _talloc_get_type_abort(v, type, location);
253  v = n;
254  }
255 
256  return head;
257 }
258 #else
259 # define talloc_list_get_type_abort(_head, _type) (_type *)(_head)
260 #endif
261 
262 /*
263  * talloc portability issues. 'const' is not part of the talloc
264  * type, but it is part of the pointer type. But only if
265  * talloc_get_type_abort() is just a cast.
266  */
267 #ifdef TALLOC_GET_TYPE_ABORT_NOOP
268 # define talloc_get_type_abort_const(ptr, type) (const type *)(ptr)
269 #else
270 # define talloc_get_type_abort_const talloc_get_type_abort
271 #endif
272 
273 /** Returns the length of a talloc array containing a string
274  *
275  * @param[in] s to return the length of.
276  */
277 static inline size_t talloc_strlen(char const *s)
278 {
279  char const *our_s = talloc_get_type_abort_const(s, char);
280  return talloc_array_length(our_s) - 1;
281 }
282 
283 TALLOC_CTX *talloc_autofree_context_global(void);
285 
286 typedef struct talloc_child_ctx_s TALLOC_CHILD_CTX;
287 
288 TALLOC_CHILD_CTX *talloc_child_ctx_init(TALLOC_CTX *ctx);
290 
291 #ifdef __cplusplus
292 }
293 #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:165
#define DIAG_ON(_x)
Definition: build.h:419
#define RCSIDH(h, id)
Definition: build.h:445
#define unlikely(_x)
Definition: build.h:378
#define DIAG_OFF(_x)
Definition: build.h:418
static fr_slen_t in
Definition: dict.h:645
talloc_free(reap)
unsigned char uint8_t
Definition: merged_model.c:30
ssize_t fr_slen_t
Definition: merged_model.c:35
static size_t array[MY_ARRAY_SIZE]
static char const * name
fr_aka_sim_id_type_t type
Functions which we wish were included in the standard talloc distribution.
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:876
char * talloc_bstrdup(TALLOC_CTX *ctx, char const *in)
Binary safe strdup function.
Definition: talloc.c:424
TALLOC_CHILD_CTX * talloc_child_ctx_init(TALLOC_CTX *ctx)
Allocate and initialize a TALLOC_CHILD_CTX.
Definition: talloc.c:926
#define talloc_get_type_abort_const
Definition: talloc.h:270
TALLOC_CTX * talloc_page_aligned_pool(TALLOC_CTX *ctx, void **start, void **end, size_t size)
Return a page aligned talloc memory pool.
Definition: talloc.c:239
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:308
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
Definition: talloc.c:333
char * talloc_buffer_append_variadic_buffer(TALLOC_CTX *ctx, char *to, int argc,...)
Concatenate to + ...
Definition: talloc.c:584
static int talloc_const_free(void const *ptr)
Free const'd memory.
Definition: talloc.h:212
void * talloc_null_ctx(void)
Retrieve the current talloc NULL ctx.
Definition: talloc.c:49
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:407
char * talloc_buffer_append_buffer(TALLOC_CTX *ctx, char *to, char const *from)
Concatenate to + from.
Definition: talloc.c:548
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:802
char * talloc_bstrndup(TALLOC_CTX *ctx, char const *in, size_t inlen)
Binary safe strndup function.
Definition: talloc.c:452
int talloc_memcmp_array(uint8_t const *a, uint8_t const *b)
Compares two talloced uint8_t arrays with memcmp.
Definition: talloc.c:660
TALLOC_CHILD_CTX * talloc_child_ctx_alloc(TALLOC_CHILD_CTX *parent)
Allocate a TALLOC_CHILD_CTX from a parent.
Definition: talloc.c:940
TALLOC_CTX * talloc_autofree_context_global(void)
Definition: talloc.c:845
char * talloc_bstr_realloc(TALLOC_CTX *ctx, char *in, size_t inlen)
Trim a bstr (char) buffer.
Definition: talloc.c:516
fr_talloc_free_func_t func
Free function.
Definition: talloc.h:92
static void _talloc_list_free(void **head, size_t offset)
Definition: talloc.h:225
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:167
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:480
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...))
Call talloc vasprintf, setting the type on the new chunk correctly.
Definition: talloc.c:380
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:357
void ** talloc_array_null_strip(void **array)
Remove a NULL termination pointer from an array of pointers.
Definition: talloc.c:770
static void * _talloc_list_get_type_abort(void *head, size_t offset, char const *type, char const *location)
Definition: talloc.h:244
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:196
void ** talloc_array_null_terminate(void **array)
Add a NULL pointer to an array of pointers.
Definition: talloc.c:740
fr_talloc_destructor_t * d
Destructor to disarm.
Definition: talloc.h:102
static TALLOC_CTX * talloc_init_const(char const *name)
Allocate a top level chunk with a constant name.
Definition: talloc.h:112
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:37
int talloc_decrease_ref_count(void const *ptr)
Decrease the reference count on a ptr.
Definition: talloc.c:708
void * uctx
uctx to pass to free function.
Definition: talloc.h:93
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:138
int(* fr_talloc_free_func_t)(void *fire_ctx, void *uctx)
Definition: talloc.h:80
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:277
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:96
int talloc_memcmp_bstr(char const *a, char const *b)
Compares two talloced char arrays with memcmp.
Definition: talloc.c:684
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:408
static fr_slen_t parent
Definition: pair.h:844
static fr_slen_t data
Definition: value.h:1259
static size_t char fr_sbuff_t size_t inlen
Definition: value.h:984
int nonnull(2, 5))
int format(printf, 5, 0))
static size_t char ** out
Definition: value.h:984