24RCSID(
"$Id: 0741bed95911bfcd5e371c7491b17b3f931ab23d $")
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 size += (hdr_size * headers);
326 if (size % page_size == 0) {
329 rounded =
ROUND_UP(size, page_size);
338 alloced = rounded + page_size;
339 pool = talloc_pool(ctx, alloced);
351 if ((uintptr_t)pool % page_size != 0) {
361 pad_size = ((uintptr_t)
next - (uintptr_t)pool);
362 if (pad_size > hdr_size) {
363 pad_size -= hdr_size;
368 padding = talloc_size(pool, pad_size);
383 fr_assert(((uintptr_t)*start % page_size) == 0);
390 fr_assert(((uintptr_t)*end_len % page_size) == 0);
400 fr_assert(((uintptr_t)*start + *end_len) <= ((uintptr_t)pool + alloced));
445 n = talloc_strdup(ctx, p);
447 talloc_set_type(
n,
char);
469 n = talloc_strndup(ctx, p, talloc_array_length(p) - 1);
471 talloc_set_type(
n,
char);
494 n = talloc_vasprintf(ctx,
fmt, ap);
497 talloc_set_type(
n,
char);
519 n = talloc_vasprintf(ctx,
fmt, ap);
521 talloc_set_type(
n,
char);
535 size_t inlen = talloc_array_length(
in);
539 p = talloc_array(ctx,
char,
inlen);
564 p = talloc_array(ctx,
char,
inlen + 1);
594 to_len = talloc_array_length(to);
595 if (to[to_len - 1] ==
'\0') to_len--;
598 n = talloc_realloc_size(ctx, to, to_len + from_len + 1);
600 fr_strerror_printf(
"Extending bstr buffer to %zu bytes failed", to_len + from_len + 1);
604 memcpy(
n + to_len, from, from_len);
605 n[to_len + from_len] =
'\0';
606 talloc_set_type(
n,
char);
629 n = talloc_array(ctx,
char,
inlen);
634 n = talloc_realloc_size(ctx,
in,
inlen + 1);
638 talloc_set_type(
n,
char);
658 size_t to_len, from_len, total_len;
661 if (!to || !from)
return NULL;
663 to_len = talloc_array_length(to);
664 from_len = talloc_array_length(from);
665 total_len = to_len + (from_len - 1);
667 out = talloc_realloc(ctx, to,
char, total_len);
668 if (!
out)
return NULL;
670 memcpy(
out + (to_len - 1), from, from_len);
671 out[total_len - 1] =
'\0';
694 va_list ap_val, ap_len;
697 size_t to_len, total_len = 0;
700 if (!to)
return NULL;
703 va_copy(ap_len, ap_val);
705 total_len += to_len = talloc_array_length(to) - 1;
710 for (i = 0; i < argc; i++) {
713 arg = va_arg(ap_len,
char *);
716 total_len += (talloc_array_length(arg) - 1);
722 if (total_len == to_len) {
728 out = talloc_realloc(ctx, to,
char, total_len + 1);
729 if (!
out)
goto finish;
736 for (i = 0; i < argc; i++) {
740 arg = va_arg(ap_val,
char *);
743 len = talloc_array_length(arg) - 1;
772 a_len = talloc_array_length(a);
773 b_len = talloc_array_length(b);
775 if (a_len > b_len)
return +1;
776 if (a_len < b_len)
return -1;
778 return memcmp(a, b, a_len);
796 a_len = talloc_array_length(a);
797 b_len = talloc_array_length(b);
799 if (a_len > b_len)
return +1;
800 if (a_len < b_len)
return -1;
802 return memcmp(a, b, a_len);
823 memcpy(&to_free, &ptr,
sizeof(to_free));
825 ref_count = talloc_reference_count(to_free);
826 if (ref_count == 0) {
829 talloc_unlink(talloc_parent(ptr), to_free);
855 if (!array)
return NULL;
857 len = talloc_array_length(array);
858 ctx = talloc_parent(array);
859 size = talloc_get_size(array) / talloc_array_length(array);
861 new = _talloc_realloc_array(ctx, array, size, len + 1, talloc_get_name(array));
862 if (!
new)
return NULL;
885 if (!array)
return NULL;
887 len = talloc_array_length(array);
888 ctx = talloc_parent(array);
889 size = talloc_get_size(array) / talloc_array_length(array);
891 if ((len - 1) == 0)
return NULL;
893 if (array[len - 1] != NULL)
return NULL;
895 new = _talloc_realloc_array(ctx, array, size, len - 1, talloc_get_name(array));
896 if (!
new)
return NULL;
913 size_t len = talloc_array_length(array);
914 char const *
const * p;
915 char const *
const * end;
917 .name = __FUNCTION__,
921 if (sep) e_rules.subs[(
uint8_t)*sep] = *sep;
923 for (p = array, end = array + len;
928 if (sep && ((p + 1) < end)) {
941 talloc_set_destructor(af, NULL);
1006 while (list->
next != NULL) {
1039 if (!child)
return NULL;
1053 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.
ssize_t fr_sbuff_in_strcpy(fr_sbuff_t *sbuff, char const *str)
Copy bytes into the sbuff up to the first \0.
ssize_t fr_sbuff_in_escape(fr_sbuff_t *sbuff, char const *in, size_t inlen, fr_sbuff_escape_rules_t const *e_rules)
Print an escaped string to an sbuff.
#define FR_SBUFF_RETURN(_func, _sbuff,...)
#define FR_SBUFF_SET_RETURN(_dst, _src)
#define FR_SBUFF(_sbuff_or_marker)
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.
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.
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 + ...
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.
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.
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.
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