24 RCSID(
"$Id: 9254b6d9c64568c0938e827812400cd36e3ae410 $")
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/sbuff.h>
30 #include <freeradius-devel/util/strerror.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;
241 size_t rounded, page_size = (
size_t)getpagesize();
242 size_t hdr_size, pool_size;
246 rounded =
ROUND_UP(size, page_size);
247 if (rounded == 0) rounded = page_size;
249 pool_size = rounded + page_size;
250 pool = talloc_pool(ctx, pool_size);
256 chunk = talloc_size(pool, 1);
257 if (!
fr_cond_assert((chunk > pool) && ((uintptr_t)chunk < ((uintptr_t)pool + rounded)))) {
263 hdr_size = (uintptr_t)chunk - (uintptr_t)pool;
273 if (((uintptr_t)
next - (uintptr_t)chunk) > 0) {
277 pad_size = ((uintptr_t)
next - (uintptr_t)chunk);
278 if (pad_size > hdr_size) {
279 pad_size -= hdr_size;
284 padding = talloc_size(pool, pad_size);
292 *end = (
void *)((uintptr_t)
next + (uintptr_t)rounded);
337 n = talloc_strdup(ctx, p);
339 talloc_set_type(
n,
char);
361 n = talloc_strndup(ctx, p, talloc_array_length(p) - 1);
363 talloc_set_type(
n,
char);
386 n = talloc_vasprintf(ctx,
fmt, ap);
389 talloc_set_type(
n,
char);
411 n = talloc_vasprintf(ctx,
fmt, ap);
413 talloc_set_type(
n,
char);
427 size_t inlen = talloc_array_length(
in);
431 p = talloc_array(ctx,
char,
inlen);
456 p = talloc_array(ctx,
char,
inlen + 1);
486 to_len = talloc_array_length(to);
487 if (to[to_len - 1] ==
'\0') to_len--;
490 n = talloc_realloc_size(ctx, to, to_len + from_len + 1);
492 fr_strerror_printf(
"Extending bstr buffer to %zu bytes failed", to_len + from_len + 1);
496 memcpy(
n + to_len, from, from_len);
497 n[to_len + from_len] =
'\0';
498 talloc_set_type(
n,
char);
521 n = talloc_array(ctx,
char,
inlen);
526 n = talloc_realloc_size(ctx,
in,
inlen + 1);
530 talloc_set_type(
n,
char);
550 size_t to_len, from_len, total_len;
553 if (!to || !from)
return NULL;
555 to_len = talloc_array_length(to);
556 from_len = talloc_array_length(from);
557 total_len = to_len + (from_len - 1);
559 out = talloc_realloc(ctx, to,
char, total_len);
560 if (!
out)
return NULL;
562 memcpy(
out + (to_len - 1), from, from_len);
563 out[total_len - 1] =
'\0';
586 va_list ap_val, ap_len;
589 size_t to_len, total_len = 0;
592 if (!to)
return NULL;
595 va_copy(ap_len, ap_val);
597 total_len += to_len = talloc_array_length(to) - 1;
602 for (i = 0; i < argc; i++) {
605 arg = va_arg(ap_len,
char *);
608 total_len += (talloc_array_length(arg) - 1);
614 if (total_len == to_len) {
620 out = talloc_realloc(ctx, to,
char, total_len + 1);
621 if (!
out)
goto finish;
628 for (i = 0; i < argc; i++) {
632 arg = va_arg(ap_val,
char *);
635 len = talloc_array_length(arg) - 1;
664 a_len = talloc_array_length(a);
665 b_len = talloc_array_length(b);
667 if (a_len > b_len)
return +1;
668 if (a_len < b_len)
return -1;
670 return memcmp(a, b, a_len);
688 a_len = talloc_array_length(a);
689 b_len = talloc_array_length(b);
691 if (a_len > b_len)
return +1;
692 if (a_len < b_len)
return -1;
694 return memcmp(a, b, a_len);
715 memcpy(&to_free, &ptr,
sizeof(to_free));
717 ref_count = talloc_reference_count(to_free);
718 if (ref_count == 0) {
721 talloc_unlink(talloc_parent(ptr), to_free);
747 if (!
array)
return NULL;
749 len = talloc_array_length(
array);
750 ctx = talloc_parent(
array);
751 size = talloc_get_size(
array) / talloc_array_length(
array);
753 new = _talloc_realloc_array(ctx,
array, size, len + 1, talloc_get_name(
array));
754 if (!
new)
return NULL;
777 if (!
array)
return NULL;
779 len = talloc_array_length(
array);
780 ctx = talloc_parent(
array);
781 size = talloc_get_size(
array) / talloc_array_length(
array);
783 if ((len - 1) == 0)
return NULL;
785 if (
array[len - 1] != NULL)
return NULL;
787 new = _talloc_realloc_array(ctx,
array, size, len - 1, talloc_get_name(
array));
788 if (!
new)
return NULL;
805 size_t len = talloc_array_length(
array);
806 char const *
const * p;
807 char const *
const * end;
809 .name = __FUNCTION__,
813 if (sep) e_rules.subs[(
uint8_t)*sep] = *sep;
820 if (sep && ((p + 1) < end)) {
833 talloc_set_destructor(af, NULL);
898 while (list->
next != NULL) {
931 if (!child)
return NULL;
945 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.
static size_t array[MY_ARRAY_SIZE]
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(_sbuff_or_marker)
TALLOC_CTX * talloc_autofree_context_thread_local(void)
Get a thread-safe autofreed ctx that will be freed when the thread or process exits.
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.
TALLOC_CHILD_CTX * talloc_child_ctx_init(TALLOC_CTX *ctx)
Allocate and initialize a TALLOC_CHILD_CTX.
static int _talloc_link_ctx_free(UNUSED void *parent, void *child)
TALLOC_CTX * talloc_page_aligned_pool(TALLOC_CTX *ctx, void **start, void **end, size_t size)
Return a page aligned talloc memory pool.
char * talloc_typed_vasprintf(TALLOC_CTX *ctx, char const *fmt, va_list ap)
Call talloc vasprintf, setting the type on the new chunk correctly.
static TALLOC_CTX * global_ctx
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 int _autofree_on_exit(void *af)
Callback to free the autofree ctx on global exit.
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
char * talloc_buffer_append_variadic_buffer(TALLOC_CTX *ctx, char *to, int argc,...)
Concatenate to + ...
void * talloc_null_ctx(void)
Retrieve the current talloc NULL ctx.
struct talloc_child_ctx_s * next
char * talloc_buffer_append_buffer(TALLOC_CTX *ctx, char *to, char const *from)
Concatenate to + from.
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.
static int _autofree_thread_local_destructor(TALLOC_CTX *af)
Ensures in the autofree ctx is manually freed, things don't explode atexit.
char * talloc_bstrndup(TALLOC_CTX *ctx, char const *in, size_t inlen)
Binary safe strndup function.
int talloc_memcmp_array(uint8_t const *a, uint8_t const *b)
Compares two talloced uint8_t arrays with memcmp.
TALLOC_CHILD_CTX * talloc_child_ctx_alloc(TALLOC_CHILD_CTX *parent)
Allocate a TALLOC_CHILD_CTX from a parent.
TALLOC_CTX * talloc_autofree_context_global(void)
char * talloc_bstr_realloc(TALLOC_CTX *ctx, char *in, size_t inlen)
Trim a bstr (char) buffer.
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.
char * talloc_bstr_append(TALLOC_CTX *ctx, char *to, char const *from, size_t from_len)
Append a bstr to a bstr.
static _Thread_local TALLOC_CTX * thread_local_ctx
char * talloc_typed_strdup_buffer(TALLOC_CTX *ctx, char const *p)
Call talloc_strndup, setting the type on the new chunk correctly.
void ** talloc_array_null_strip(void **array)
Remove a NULL termination pointer from an array of pointers.
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 _child_ctx_free(TALLOC_CHILD_CTX *list)
void ** talloc_array_null_terminate(void **array)
Add a NULL pointer to an array of pointers.
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, 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.
void talloc_destructor_disarm(fr_talloc_destructor_t *d)
Disarm a destructor and free all memory allocated in the trigger ctxs.
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.
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.
fr_talloc_destructor_t * d
Destructor to disarm.
static TALLOC_CTX * talloc_init_const(char const *name)
Allocate a top level chunk with a constant name.
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)
FR_SBUFF_SET_RETURN(sbuff, &our_sbuff)
static size_t char fr_sbuff_t size_t inlen
static size_t char ** out