24RCSID(
"$Id: bc2a12488c2f12b006078df9375ece98e19e6b16 $")
26#include <freeradius-devel/util/atexit.h>
27#include <freeradius-devel/util/debug.h>
28#include <freeradius-devel/util/dlist.h>
29#include <freeradius-devel/util/syserror.h>
54 tmp = talloc(NULL,
bool);
55 null_ctx = talloc_parent(tmp);
67 talloc_set_destructor(d->
ds, NULL);
79 talloc_set_destructor(ds->
d, NULL);
115 memcpy(&d->
uctx, &uctx,
sizeof(d->
uctx));
141 talloc_set_destructor(d->
ds, NULL);
145 talloc_set_destructor(d, NULL);
203 rounded =
ROUND_UP(size, alignment);
204 if (rounded == 0) rounded = alignment;
206 array_size = rounded + alignment;
207 array = talloc_array(ctx,
uint8_t, array_size);
233 pool = talloc_pool(NULL, 1024);
239 chunk = talloc_size(pool, 1);
240 if (
unlikely(chunk == NULL))
goto oom;
246 if (!
fr_cond_assert((chunk > pool) && ((uintptr_t)chunk < ((uintptr_t)pool + 1024)))) {
260 t_hdr_size = (uintptr_t)chunk - (uintptr_t)pool;
273 static pthread_once_t once_control = PTHREAD_ONCE_INIT;
310 size_t rounded, alloced, page_size = (
size_t)getpagesize();
316 if (hdr_size < 0)
return NULL;
318 size += (hdr_size * headers);
328 if (size % page_size == 0) {
331 rounded =
ROUND_UP(size, page_size);
340 alloced = rounded + page_size;
341 pool = talloc_pool(ctx, alloced);
353 if ((uintptr_t)pool % page_size != 0) {
363 pad_size = ((uintptr_t)
next - (uintptr_t)pool);
364 if (pad_size > (
size_t) hdr_size) {
365 pad_size -= hdr_size;
370 padding = talloc_size(pool, pad_size);
385 fr_assert(((uintptr_t)*start % page_size) == 0);
392 fr_assert(((uintptr_t)*end_len % page_size) == 0);
402 fr_assert(((uintptr_t)*start + *end_len) <= ((uintptr_t)pool + alloced));
420 size_t old_size = talloc_get_size(ptr);
423 void *
new = _talloc_realloc_array(ctx, ptr, elem_size,
count,
name);
424 if (!
new)
return NULL;
426 new_size = talloc_array_length((
uint8_t *)
new);
427 if (new_size > old_size) {
428 memset((
uint8_t *)
new + old_size, 0, new_size - old_size);
477 talloc_set_type(
n,
char);
501 talloc_set_type(
n,
char);
528 talloc_set_type(
n,
char);
551 n = talloc_vasprintf(ctx,
fmt, ap);
554 talloc_set_type(
n,
char);
576 n = talloc_vasprintf(ctx,
fmt, ap);
578 talloc_set_type(
n,
char);
592 size_t inlen = talloc_array_length(
in);
596 p = talloc_array(ctx,
char,
inlen);
621 p = talloc_array(ctx,
char,
inlen + 1);
651 to_len = talloc_array_length(to);
652 if (to[to_len - 1] ==
'\0') to_len--;
655 n = talloc_realloc_size(ctx, to, to_len + from_len + 1);
657 fr_strerror_printf(
"Extending bstr buffer to %zu bytes failed", to_len + from_len + 1);
661 memcpy(
n + to_len, from, from_len);
662 n[to_len + from_len] =
'\0';
663 talloc_set_type(
n,
char);
686 n = talloc_array(ctx,
char,
inlen + 1);
692 n = talloc_realloc_size(ctx,
in,
inlen + 1);
696 talloc_set_type(
n,
char);
716 size_t to_len, from_len, total_len;
719 if (!to || !from)
return NULL;
721 to_len = talloc_array_length(to);
722 from_len = talloc_array_length(from);
723 total_len = to_len + (from_len - 1);
725 out = talloc_realloc(ctx, to,
char, total_len);
726 if (!
out)
return NULL;
728 memcpy(
out + (to_len - 1), from, from_len);
729 out[total_len - 1] =
'\0';
752 va_list ap_val, ap_len;
755 size_t to_len, total_len = 0;
758 if (!to)
return NULL;
761 va_copy(ap_len, ap_val);
768 for (i = 0; i < argc; i++) {
771 arg = va_arg(ap_len,
char *);
780 if (total_len == to_len) {
786 out = talloc_realloc(ctx, to,
char, total_len + 1);
787 if (!
out)
goto finish;
794 for (i = 0; i < argc; i++) {
798 arg = va_arg(ap_val,
char *);
830 a_len = talloc_array_length(a);
831 b_len = talloc_array_length(b);
833 if (a_len > b_len)
return +1;
834 if (a_len < b_len)
return -1;
836 return memcmp(a, b, a_len);
854 a_len = talloc_array_length(a);
855 b_len = talloc_array_length(b);
857 if (a_len > b_len)
return +1;
858 if (a_len < b_len)
return -1;
860 return memcmp(a, b, a_len);
881 memcpy(&to_free, &ptr,
sizeof(to_free));
883 ref_count = talloc_reference_count(to_free);
884 if (ref_count == 0) {
887 talloc_unlink(talloc_parent(ptr), to_free);
913 if (!array)
return NULL;
915 len = talloc_array_length(array);
916 ctx = talloc_parent(array);
917 size = talloc_get_size(array) / talloc_array_length(array);
919 new = _talloc_realloc_array(ctx, array, size, len + 1, talloc_get_name(array));
920 if (!
new)
return NULL;
943 if (!array)
return NULL;
945 len = talloc_array_length(array);
946 ctx = talloc_parent(array);
947 size = talloc_get_size(array) / talloc_array_length(array);
949 if ((len - 1) == 0)
return NULL;
951 if (array[len - 1] != NULL)
return NULL;
953 new = _talloc_realloc_array(ctx, array, size, len - 1, talloc_get_name(array));
954 if (!
new)
return NULL;
964 talloc_set_destructor(af, NULL);
1031 while (list->
next != NULL) {
1064 if (!child)
return NULL;
1078 if (!child)
return NULL;
static int const char * fmt
unsigned int fr_atexit_global_disarm(bool uctx_scope, fr_atexit_t func, void const *uctx)
Remove a specific global destructor (without executing it)
#define fr_atexit_thread_local_disarm(...)
#define fr_atexit_global(_func, _uctx)
Add a free function to the global free list.
#define fr_atexit_thread_local(_name, _free, _uctx)
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
#define ROUND_UP(_num, _mul)
Round up - Works in all cases, but is slower.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
void ** talloc_array_null_terminate(void **array)
Add a NULL pointer to an array of pointers.
static int _talloc_destructor_fire(fr_talloc_destructor_t *d)
Called with the fire_ctx is freed.
char * talloc_bstrdup(TALLOC_CTX *ctx, char const *in)
Binary safe strdup function.
static int _talloc_link_ctx_free(UNUSED void *parent, void *child)
TALLOC_CHILD_CTX * talloc_child_ctx_alloc(TALLOC_CHILD_CTX *parent)
Allocate a TALLOC_CHILD_CTX from a parent.
static TALLOC_CTX * global_ctx
static int _autofree_on_exit(void *af)
Callback to free the autofree ctx on global exit.
char * talloc_typed_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap)
Call talloc vasprintf, setting the type on the new chunk correctly.
struct talloc_child_ctx_s * next
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.
char * talloc_typed_strdup_buffer(TALLOC_CTX *ctx, char const *p)
Call talloc_strndup, setting the type on the new chunk correctly.
ssize_t talloc_hdr_size(void)
Calculate the size of the talloc chunk header.
TALLOC_CTX * talloc_autofree_context_global(void)
static int _autofree_thread_local_destructor(TALLOC_CTX *af)
Ensures in the autofree ctx is manually freed, things don't explode atexit.
TALLOC_CHILD_CTX * talloc_child_ctx_init(TALLOC_CTX *ctx)
Allocate and initialize a TALLOC_CHILD_CTX.
int talloc_memcmp_array(uint8_t const *a, uint8_t const *b)
Compares two talloced uint8_t arrays with memcmp.
char * talloc_buffer_append_variadic_buffer(TALLOC_CTX *ctx, char *to, int argc,...)
Concatenate to + ...
void * _talloc_realloc_zero(const void *ctx, void *ptr, size_t elem_size, unsigned count, const char *name)
Version of talloc_realloc which zeroes out freshly allocated memory.
char * talloc_bstr_realloc(TALLOC_CTX *ctx, char *in, size_t inlen)
Trim a bstr (char) buffer.
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
TALLOC_CTX * talloc_aligned_array(TALLOC_CTX *ctx, void **start, size_t alignment, size_t size)
Return a page aligned talloc memory array.
static int _talloc_destructor_disarm(fr_talloc_destructor_disarm_t *ds)
Called when the disarm_ctx ctx is freed.
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.
static void _talloc_hdr_size(void)
Calculate the size of talloc chunk headers, once, on startup.
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.
static _Thread_local TALLOC_CTX * thread_local_ctx
char * talloc_bstrndup(TALLOC_CTX *ctx, char const *in, size_t inlen)
Binary safe strndup function.
static size_t t_hdr_size
How big the chunk header is.
static int _child_ctx_free(TALLOC_CHILD_CTX *list)
void * talloc_null_ctx(void)
Retrieve the current talloc NULL ctx.
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.
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
void talloc_free_data(void *data)
A wrapper that can be passed to tree or hash alloc functions that take a fr_free_t.
int talloc_decrease_ref_count(void const *ptr)
Decrease the reference count on a ptr.
char * talloc_typed_strndup(TALLOC_CTX *ctx, char const *p, size_t len)
Call talloc_strndup, setting the type on the new chunk correctly.
TALLOC_CTX * talloc_autofree_context_thread_local(void)
Get a thread-safe autofreed ctx that will be freed when the thread or process exits.
char * talloc_buffer_append_buffer(TALLOC_CTX *ctx, char *to, char const *from)
Concatenate to + from.
void ** talloc_array_null_strip(void **array)
Remove a NULL termination pointer from an array of pointers.
char * talloc_bstr_append(TALLOC_CTX *ctx, char *to, char const *from, size_t from_len)
Append a bstr to a bstr.
void talloc_destructor_disarm(fr_talloc_destructor_t *d)
Disarm a destructor and free all memory allocated in the trigger ctxs.
int talloc_memcmp_bstr(char const *a, char const *b)
Compares two talloced char arrays with memcmp.
static int _autofree_global_destructor(TALLOC_CTX *af)
Ensures in the autofree ctx is manually freed, things don't explode atexit.
#define talloc_strndup(_ctx, _str, _len)
fr_talloc_free_func_t func
Free function.
static TALLOC_CTX * talloc_init_const(char const *name)
Allocate a top level chunk with a constant name.
fr_talloc_destructor_t * d
Destructor to disarm.
void * uctx
uctx to pass to free function.
int(* fr_talloc_free_func_t)(void *fire_ctx, void *uctx)
fr_talloc_destructor_disarm_t * ds
Chunk to free.
#define talloc_strdup(_ctx, _str)
static size_t talloc_strlen(char const *s)
Returns the length of a talloc array containing a string.
Structure to record a destructor to disarm if a child talloc chunk is freed.
Structure to record a destructor operation on a specific talloc chunk.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const(_msg)
static size_t char fr_sbuff_t size_t inlen
static size_t char ** out