2 Samba Unix SMB/CIFS implementation.
4 Samba trivial allocation library - new interface
6 NOTE: Please read talloc_guide.txt for full documentation
8 Copyright (C) Andrew Tridgell 2004
10 ** NOTE! The following LGPL license applies to the talloc
11 ** library. This does NOT imply that all of Samba is released
14 This library is free software; you can redistribute it and/or
15 modify it under the terms of the GNU Lesser General Public
16 License as published by the Free Software Foundation; either
17 version 2 of the License, or (at your option) any later version.
19 This library is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 Lesser General Public License for more details.
24 You should have received a copy of the GNU Lesser General Public
25 License along with this library; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 inspired by http://swapped.cc/halloc/
35 #if ((SAMBA_VERSION_MAJOR==3)&&(SAMBA_VERSION_MINOR<9))
36 /* This is to circumvent SAMBA3's paranoid malloc checker. Here in this file
37 * we trust ourselves... */
52 /* assume a modern system */
56 /* use this to force every realloc to change the pointer, to stress test
57 code that might not cope */
58 #define ALWAYS_REALLOC 0
61 #define MAX_TALLOC_SIZE 0x10000000
62 #define TALLOC_MAGIC 0xe814ec70
63 #define TALLOC_FLAG_FREE 0x01
64 #define TALLOC_FLAG_LOOP 0x02
65 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
67 /* by default we abort when given a bad pointer (such as when talloc_free() is called
68 on a pointer that came from malloc() */
70 #define TALLOC_ABORT(reason) abort()
73 #ifndef discard_const_p
74 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
75 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
77 # define discard_const_p(type, ptr) ((type *)(ptr))
81 /* this null_context is only used if talloc_enable_leak_report() or
82 talloc_enable_leak_report_full() is called, otherwise it remains
85 static const void *null_context
;
86 static void *cleanup_context
;
89 struct talloc_reference_handle
{
90 struct talloc_reference_handle
*next
, *prev
;
94 typedef int (*talloc_destructor_t
)(void *);
97 struct talloc_chunk
*next
, *prev
;
98 struct talloc_chunk
*parent
, *child
;
99 struct talloc_reference_handle
*refs
;
100 talloc_destructor_t destructor
;
106 /* 16 byte alignment seems to keep everyone happy */
107 #define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
108 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
110 /* panic if we get a bad magic value */
111 static struct talloc_chunk
*talloc_chunk_from_ptr(const void *ptr
)
113 const char *pp
= ptr
;
114 struct talloc_chunk
*tc
= discard_const_p(struct talloc_chunk
, pp
- TC_HDR_SIZE
);
115 if ((tc
->flags
& ~0xF) != TALLOC_MAGIC
) {
116 TALLOC_ABORT("Bad talloc magic value - unknown value");
118 if (tc
->flags
& TALLOC_FLAG_FREE
) {
119 TALLOC_ABORT("Bad talloc magic value - double free");
124 /* hook into the front of the list */
125 #define _TLIST_ADD(list, p) \
129 (p)->next = (p)->prev = NULL; \
131 (list)->prev = (p); \
132 (p)->next = (list); \
138 /* remove an element from a list - element doesn't have to be in list. */
139 #define _TLIST_REMOVE(list, p) \
141 if ((p) == (list)) { \
142 (list) = (p)->next; \
143 if (list) (list)->prev = NULL; \
145 if ((p)->prev) (p)->prev->next = (p)->next; \
146 if ((p)->next) (p)->next->prev = (p)->prev; \
148 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
153 return the parent chunk of a pointer
155 static struct talloc_chunk
*talloc_parent_chunk(const void *ptr
)
157 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
158 while (tc
->prev
) tc
=tc
->prev
;
162 void *talloc_parent(const void *ptr
)
164 struct talloc_chunk
*tc
= talloc_parent_chunk(ptr
);
165 return tc
? TC_PTR_FROM_CHUNK(tc
) : NULL
;
169 Allocate a bit of memory as a child of an existing pointer
171 void *_talloc(const void *context
, size_t size
)
173 struct talloc_chunk
*tc
;
175 if (context
== NULL
) {
176 context
= null_context
;
179 if (size
>= MAX_TALLOC_SIZE
) {
183 tc
= malloc(TC_HDR_SIZE
+size
);
184 if (tc
== NULL
) return NULL
;
187 tc
->flags
= TALLOC_MAGIC
;
188 tc
->destructor
= NULL
;
194 struct talloc_chunk
*parent
= talloc_chunk_from_ptr(context
);
199 parent
->child
->parent
= NULL
;
202 _TLIST_ADD(parent
->child
, tc
);
204 tc
->next
= tc
->prev
= tc
->parent
= NULL
;
207 return TC_PTR_FROM_CHUNK(tc
);
212 setup a destructor to be called on free of a pointer
213 the destructor should return 0 on success, or -1 on failure.
214 if the destructor fails then the free is failed, and the memory can
215 be continued to be used
217 void talloc_set_destructor(const void *ptr
, int (*destructor
)(void *))
219 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
220 tc
->destructor
= destructor
;
224 increase the reference count on a piece of memory.
226 void talloc_increase_ref_count(const void *ptr
)
228 talloc_reference(null_context
, ptr
);
232 helper for talloc_reference()
234 static int talloc_reference_destructor(void *ptr
)
236 struct talloc_reference_handle
*handle
= ptr
;
237 struct talloc_chunk
*tc1
= talloc_chunk_from_ptr(ptr
);
238 struct talloc_chunk
*tc2
= talloc_chunk_from_ptr(handle
->ptr
);
239 if (tc1
->destructor
!= (talloc_destructor_t
)-1) {
240 tc1
->destructor
= NULL
;
242 _TLIST_REMOVE(tc2
->refs
, handle
);
248 make a secondary reference to a pointer, hanging off the given context.
249 the pointer remains valid until both the original caller and this given
252 the major use for this is when two different structures need to reference the
253 same underlying data, and you want to be able to free the two instances separately,
256 void *talloc_reference(const void *context
, const void *ptr
)
258 struct talloc_chunk
*tc
;
259 struct talloc_reference_handle
*handle
;
260 if (ptr
== NULL
) return NULL
;
262 tc
= talloc_chunk_from_ptr(ptr
);
263 handle
= talloc_named_const(context
, sizeof(*handle
), TALLOC_MAGIC_REFERENCE
);
265 if (handle
== NULL
) return NULL
;
267 /* note that we hang the destructor off the handle, not the
268 main context as that allows the caller to still setup their
269 own destructor on the context if they want to */
270 talloc_set_destructor(handle
, talloc_reference_destructor
);
271 handle
->ptr
= discard_const_p(void, ptr
);
272 _TLIST_ADD(tc
->refs
, handle
);
277 remove a secondary reference to a pointer. This undo's what
278 talloc_reference() has done. The context and pointer arguments
279 must match those given to a talloc_reference()
281 static int talloc_unreference(const void *context
, const void *ptr
)
283 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
284 struct talloc_reference_handle
*h
;
286 if (context
== NULL
) {
287 context
= null_context
;
290 for (h
=tc
->refs
;h
;h
=h
->next
) {
291 struct talloc_chunk
*p
= talloc_parent_chunk(h
);
292 if ((p
==NULL
&& context
==NULL
) || TC_PTR_FROM_CHUNK(p
) == context
) break;
298 talloc_set_destructor(h
, NULL
);
299 _TLIST_REMOVE(tc
->refs
, h
);
305 remove a specific parent context from a pointer. This is a more
306 controlled varient of talloc_free()
308 int talloc_unlink(const void *context
, void *ptr
)
310 struct talloc_chunk
*tc_p
, *new_p
;
317 if (context
== NULL
) {
318 context
= null_context
;
321 if (talloc_unreference(context
, ptr
) == 0) {
325 if (context
== NULL
) {
326 if (talloc_parent_chunk(ptr
) != NULL
) {
330 if (talloc_chunk_from_ptr(context
) != talloc_parent_chunk(ptr
)) {
335 tc_p
= talloc_chunk_from_ptr(ptr
);
337 if (tc_p
->refs
== NULL
) {
338 return talloc_free(ptr
);
341 new_p
= talloc_parent_chunk(tc_p
->refs
);
343 new_parent
= TC_PTR_FROM_CHUNK(new_p
);
348 if (talloc_unreference(new_parent
, ptr
) != 0) {
352 talloc_steal(new_parent
, ptr
);
358 add a name to an existing pointer - va_list version
360 static void talloc_set_name_v(const void *ptr
, const char *fmt
, va_list ap
) PRINTF_ATTRIBUTE(2,0);
362 static void talloc_set_name_v(const void *ptr
, const char *fmt
, va_list ap
)
364 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
365 tc
->name
= talloc_vasprintf(ptr
, fmt
, ap
);
367 talloc_set_name_const(tc
->name
, ".name");
372 add a name to an existing pointer
374 void talloc_set_name(const void *ptr
, const char *fmt
, ...)
378 talloc_set_name_v(ptr
, fmt
, ap
);
383 more efficient way to add a name to a pointer - the name must point to a
386 void talloc_set_name_const(const void *ptr
, const char *name
)
388 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
393 create a named talloc pointer. Any talloc pointer can be named, and
394 talloc_named() operates just like talloc() except that it allows you
397 void *talloc_named(const void *context
, size_t size
, const char *fmt
, ...)
402 ptr
= _talloc(context
, size
);
403 if (ptr
== NULL
) return NULL
;
406 talloc_set_name_v(ptr
, fmt
, ap
);
413 create a named talloc pointer. Any talloc pointer can be named, and
414 talloc_named() operates just like talloc() except that it allows you
417 void *talloc_named_const(const void *context
, size_t size
, const char *name
)
421 ptr
= _talloc(context
, size
);
426 talloc_set_name_const(ptr
, name
);
432 return the name of a talloc ptr, or "UNNAMED"
434 const char *talloc_get_name(const void *ptr
)
436 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
437 if (tc
->name
== TALLOC_MAGIC_REFERENCE
) {
448 check if a pointer has the given name. If it does, return the pointer,
449 otherwise return NULL
451 void *talloc_check_name(const void *ptr
, const char *name
)
454 if (ptr
== NULL
) return NULL
;
455 pname
= talloc_get_name(ptr
);
456 if (pname
== name
|| strcmp(pname
, name
) == 0) {
457 return discard_const_p(void, ptr
);
464 this is for compatibility with older versions of talloc
466 void *talloc_init(const char *fmt
, ...)
471 talloc_enable_null_tracking();
473 ptr
= _talloc(NULL
, 0);
474 if (ptr
== NULL
) return NULL
;
477 talloc_set_name_v(ptr
, fmt
, ap
);
484 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
485 should probably not be used in new code. It's in here to keep the talloc
486 code consistent across Samba 3 and 4.
488 void talloc_free_children(void *ptr
)
490 struct talloc_chunk
*tc
;
496 tc
= talloc_chunk_from_ptr(ptr
);
499 /* we need to work out who will own an abandoned child
500 if it cannot be freed. In priority order, the first
501 choice is owner of any remaining reference to this
502 pointer, the second choice is our parent, and the
503 final choice is the null context. */
504 void *child
= TC_PTR_FROM_CHUNK(tc
->child
);
505 const void *new_parent
= null_context
;
506 if (tc
->child
->refs
) {
507 struct talloc_chunk
*p
= talloc_parent_chunk(tc
->child
->refs
);
508 if (p
) new_parent
= TC_PTR_FROM_CHUNK(p
);
510 if (talloc_free(child
) == -1) {
511 if (new_parent
== null_context
) {
512 struct talloc_chunk
*p
= talloc_parent_chunk(ptr
);
513 if (p
) new_parent
= TC_PTR_FROM_CHUNK(p
);
515 talloc_steal(new_parent
, child
);
521 free a talloc pointer. This also frees all child pointers of this
524 return 0 if the memory is actually freed, otherwise -1. The memory
525 will not be freed if the ref_count is > 1 or the destructor (if
526 any) returns non-zero
528 int talloc_free(void *ptr
)
530 struct talloc_chunk
*tc
;
536 tc
= talloc_chunk_from_ptr(ptr
);
539 talloc_reference_destructor(tc
->refs
);
543 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
544 /* we have a free loop - stop looping */
548 if (tc
->destructor
) {
549 talloc_destructor_t d
= tc
->destructor
;
550 if (d
== (talloc_destructor_t
)-1) {
553 tc
->destructor
= (talloc_destructor_t
)-1;
558 tc
->destructor
= NULL
;
561 tc
->flags
|= TALLOC_FLAG_LOOP
;
563 talloc_free_children(ptr
);
566 _TLIST_REMOVE(tc
->parent
->child
, tc
);
567 if (tc
->parent
->child
) {
568 tc
->parent
->child
->parent
= tc
->parent
;
571 if (tc
->prev
) tc
->prev
->next
= tc
->next
;
572 if (tc
->next
) tc
->next
->prev
= tc
->prev
;
575 tc
->flags
|= TALLOC_FLAG_FREE
;
584 A talloc version of realloc. The context argument is only used if
587 void *_talloc_realloc(const void *context
, void *ptr
, size_t size
, const char *name
)
589 struct talloc_chunk
*tc
;
592 /* size zero is equivalent to free() */
598 if (size
>= MAX_TALLOC_SIZE
) {
602 /* realloc(NULL) is equavalent to malloc() */
604 return talloc_named_const(context
, size
, name
);
607 tc
= talloc_chunk_from_ptr(ptr
);
609 /* don't allow realloc on referenced pointers */
614 /* by resetting magic we catch users of the old memory */
615 tc
->flags
|= TALLOC_FLAG_FREE
;
618 new_ptr
= malloc(size
+ TC_HDR_SIZE
);
620 memcpy(new_ptr
, tc
, tc
->size
+ TC_HDR_SIZE
);
624 new_ptr
= realloc(tc
, size
+ TC_HDR_SIZE
);
627 tc
->flags
&= ~TALLOC_FLAG_FREE
;
632 tc
->flags
&= ~TALLOC_FLAG_FREE
;
634 tc
->parent
->child
= new_ptr
;
637 tc
->child
->parent
= new_ptr
;
648 talloc_set_name_const(TC_PTR_FROM_CHUNK(tc
), name
);
650 return TC_PTR_FROM_CHUNK(tc
);
654 move a lump of memory from one talloc context to another return the
655 ptr on success, or NULL if it could not be transferred.
656 passing NULL as ptr will always return NULL with no side effects.
658 void *talloc_steal(const void *new_ctx
, const void *ptr
)
660 struct talloc_chunk
*tc
, *new_tc
;
666 if (new_ctx
== NULL
) {
667 new_ctx
= null_context
;
670 tc
= talloc_chunk_from_ptr(ptr
);
672 if (new_ctx
== NULL
) {
674 _TLIST_REMOVE(tc
->parent
->child
, tc
);
675 if (tc
->parent
->child
) {
676 tc
->parent
->child
->parent
= tc
->parent
;
679 if (tc
->prev
) tc
->prev
->next
= tc
->next
;
680 if (tc
->next
) tc
->next
->prev
= tc
->prev
;
683 tc
->parent
= tc
->next
= tc
->prev
= NULL
;
684 return discard_const_p(void, ptr
);
687 new_tc
= talloc_chunk_from_ptr(new_ctx
);
690 return discard_const_p(void, ptr
);
694 _TLIST_REMOVE(tc
->parent
->child
, tc
);
695 if (tc
->parent
->child
) {
696 tc
->parent
->child
->parent
= tc
->parent
;
699 if (tc
->prev
) tc
->prev
->next
= tc
->next
;
700 if (tc
->next
) tc
->next
->prev
= tc
->prev
;
704 if (new_tc
->child
) new_tc
->child
->parent
= NULL
;
705 _TLIST_ADD(new_tc
->child
, tc
);
707 return discard_const_p(void, ptr
);
711 return the total size of a talloc pool (subtree)
713 off_t
talloc_total_size(const void *ptr
)
716 struct talloc_chunk
*c
, *tc
;
725 tc
= talloc_chunk_from_ptr(ptr
);
727 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
731 tc
->flags
|= TALLOC_FLAG_LOOP
;
734 for (c
=tc
->child
;c
;c
=c
->next
) {
735 total
+= talloc_total_size(TC_PTR_FROM_CHUNK(c
));
738 tc
->flags
&= ~TALLOC_FLAG_LOOP
;
744 return the total number of blocks in a talloc pool (subtree)
746 off_t
talloc_total_blocks(const void *ptr
)
749 struct talloc_chunk
*c
, *tc
= talloc_chunk_from_ptr(ptr
);
751 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
755 tc
->flags
|= TALLOC_FLAG_LOOP
;
758 for (c
=tc
->child
;c
;c
=c
->next
) {
759 total
+= talloc_total_blocks(TC_PTR_FROM_CHUNK(c
));
762 tc
->flags
&= ~TALLOC_FLAG_LOOP
;
768 return the number of external references to a pointer
770 static int talloc_reference_count(const void *ptr
)
772 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
773 struct talloc_reference_handle
*h
;
776 for (h
=tc
->refs
;h
;h
=h
->next
) {
783 report on memory usage by all children of a pointer, giving a full tree view
785 void talloc_report_depth(const void *ptr
, FILE *f
, int depth
)
787 struct talloc_chunk
*c
, *tc
= talloc_chunk_from_ptr(ptr
);
789 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
793 tc
->flags
|= TALLOC_FLAG_LOOP
;
795 for (c
=tc
->child
;c
;c
=c
->next
) {
796 if (c
->name
== TALLOC_MAGIC_REFERENCE
) {
797 struct talloc_reference_handle
*handle
= TC_PTR_FROM_CHUNK(c
);
798 const char *name2
= talloc_get_name(handle
->ptr
);
799 fprintf(f
, "%*sreference to: %s\n", depth
*4, "", name2
);
801 const char *name
= talloc_get_name(TC_PTR_FROM_CHUNK(c
));
802 fprintf(f
, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n",
805 (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c
)),
806 (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c
)),
807 talloc_reference_count(TC_PTR_FROM_CHUNK(c
)));
808 talloc_report_depth(TC_PTR_FROM_CHUNK(c
), f
, depth
+1);
811 tc
->flags
&= ~TALLOC_FLAG_LOOP
;
815 report on memory usage by all children of a pointer, giving a full tree view
817 void talloc_report_full(const void *ptr
, FILE *f
)
822 if (ptr
== NULL
) return;
824 fprintf(f
,"full talloc report on '%s' (total %lu bytes in %lu blocks)\n",
825 talloc_get_name(ptr
),
826 (unsigned long)talloc_total_size(ptr
),
827 (unsigned long)talloc_total_blocks(ptr
));
829 talloc_report_depth(ptr
, f
, 1);
834 report on memory usage by all children of a pointer
836 void talloc_report(const void *ptr
, FILE *f
)
838 struct talloc_chunk
*c
, *tc
;
843 if (ptr
== NULL
) return;
845 fprintf(f
,"talloc report on '%s' (total %lu bytes in %lu blocks)\n",
846 talloc_get_name(ptr
),
847 (unsigned long)talloc_total_size(ptr
),
848 (unsigned long)talloc_total_blocks(ptr
));
850 tc
= talloc_chunk_from_ptr(ptr
);
852 for (c
=tc
->child
;c
;c
=c
->next
) {
853 fprintf(f
, "\t%-30s contains %6lu bytes in %3lu blocks\n",
854 talloc_get_name(TC_PTR_FROM_CHUNK(c
)),
855 (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c
)),
856 (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c
)));
862 report on any memory hanging off the null context
864 static void talloc_report_null(void)
866 if (talloc_total_size(null_context
) != 0) {
867 talloc_report(null_context
, stderr
);
872 report on any memory hanging off the null context
874 static void talloc_report_null_full(void)
876 if (talloc_total_size(null_context
) != 0) {
877 talloc_report_full(null_context
, stderr
);
882 enable tracking of the NULL context
884 void talloc_enable_null_tracking(void)
886 if (null_context
== NULL
) {
887 null_context
= talloc_named_const(NULL
, 0, "null_context");
892 /* Ugly calls to Samba-specific sprintf_append... JRA. */
895 report on memory usage by all children of a pointer, giving a full tree view
897 static void talloc_report_depth_str(const void *ptr
, char **pps
, ssize_t
*plen
, size_t *pbuflen
, int depth
)
899 struct talloc_chunk
*c
, *tc
= talloc_chunk_from_ptr(ptr
);
901 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
905 tc
->flags
|= TALLOC_FLAG_LOOP
;
907 for (c
=tc
->child
;c
;c
=c
->next
) {
908 if (c
->name
== TALLOC_MAGIC_REFERENCE
) {
909 struct talloc_reference_handle
*handle
= TC_PTR_FROM_CHUNK(c
);
910 const char *name2
= talloc_get_name(handle
->ptr
);
912 sprintf_append(NULL
, pps
, plen
, pbuflen
,
913 "%*sreference to: %s\n", depth
*4, "", name2
);
916 const char *name
= talloc_get_name(TC_PTR_FROM_CHUNK(c
));
918 sprintf_append(NULL
, pps
, plen
, pbuflen
,
919 "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n",
922 (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c
)),
923 (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c
)),
924 talloc_reference_count(TC_PTR_FROM_CHUNK(c
)));
926 talloc_report_depth_str(TC_PTR_FROM_CHUNK(c
), pps
, plen
, pbuflen
, depth
+1);
929 tc
->flags
&= ~TALLOC_FLAG_LOOP
;
933 report on memory usage by all children of a pointer
935 char *talloc_describe_all(void)
941 if (null_context
== NULL
) {
945 sprintf_append(NULL
, &s
, &len
, &buflen
,
946 "full talloc report on '%s' (total %lu bytes in %lu blocks)\n",
947 talloc_get_name(null_context
),
948 (unsigned long)talloc_total_size(null_context
),
949 (unsigned long)talloc_total_blocks(null_context
));
954 talloc_report_depth_str(null_context
, &s
, &len
, &buflen
, 1);
960 enable leak reporting on exit
962 void talloc_enable_leak_report(void)
964 talloc_enable_null_tracking();
965 atexit(talloc_report_null
);
969 enable full leak reporting on exit
971 void talloc_enable_leak_report_full(void)
973 talloc_enable_null_tracking();
974 atexit(talloc_report_null_full
);
978 talloc and zero memory.
980 void *_talloc_zero(const void *ctx
, size_t size
, const char *name
)
982 void *p
= talloc_named_const(ctx
, size
, name
);
985 memset(p
, '\0', size
);
993 memdup with a talloc.
995 void *_talloc_memdup(const void *t
, const void *p
, size_t size
, const char *name
)
997 void *newp
= talloc_named_const(t
, size
, name
);
1000 memcpy(newp
, p
, size
);
1007 strdup with a talloc
1009 char *talloc_strdup(const void *t
, const char *p
)
1015 ret
= talloc_memdup(t
, p
, strlen(p
) + 1);
1017 talloc_set_name_const(ret
, ret
);
1023 append to a talloced string
1025 char *talloc_append_string(const void *t
, char *orig
, const char *append
)
1028 size_t olen
= strlen(orig
);
1029 size_t alenz
= strlen(append
) + 1;
1034 ret
= talloc_realloc(t
, orig
, char, olen
+ alenz
);
1038 /* append the string with the trailing \0 */
1039 memcpy(&ret
[olen
], append
, alenz
);
1045 strndup with a talloc
1047 char *talloc_strndup(const void *t
, const char *p
, size_t n
)
1052 for (len
=0; len
<n
&& p
[len
]; len
++) ;
1054 ret
= _talloc(t
, len
+ 1);
1055 if (!ret
) { return NULL
; }
1056 memcpy(ret
, p
, len
);
1058 talloc_set_name_const(ret
, ret
);
1064 #define VA_COPY(dest, src) va_copy(dest, src)
1065 #elif defined(HAVE___VA_COPY)
1066 #define VA_COPY(dest, src) __va_copy(dest, src)
1068 #define VA_COPY(dest, src) (dest) = (src)
1072 char *talloc_vasprintf(const void *t
, const char *fmt
, va_list ap
)
1080 len
= vsnprintf(NULL
, 0, fmt
, ap2
);
1082 ret
= _talloc(t
, len
+1);
1085 vsnprintf(ret
, len
+1, fmt
, ap2
);
1086 talloc_set_name_const(ret
, ret
);
1094 Perform string formatting, and return a pointer to newly allocated
1095 memory holding the result, inside a memory pool.
1097 char *talloc_asprintf(const void *t
, const char *fmt
, ...)
1103 ret
= talloc_vasprintf(t
, fmt
, ap
);
1110 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1111 * and return @p s, which may have moved. Good for gradually
1112 * accumulating output into a string buffer.
1115 static char *talloc_vasprintf_append(char *s
, const char *fmt
, va_list ap
) PRINTF_ATTRIBUTE(2,0);
1117 static char *talloc_vasprintf_append(char *s
, const char *fmt
, va_list ap
)
1119 struct talloc_chunk
*tc
;
1124 return talloc_vasprintf(NULL
, fmt
, ap
);
1127 tc
= talloc_chunk_from_ptr(s
);
1131 s_len
= tc
->size
- 1;
1132 len
= vsnprintf(NULL
, 0, fmt
, ap2
);
1134 s
= talloc_realloc(NULL
, s
, char, s_len
+ len
+1);
1135 if (!s
) return NULL
;
1139 vsnprintf(s
+s_len
, len
+1, fmt
, ap2
);
1140 talloc_set_name_const(s
, s
);
1146 Realloc @p s to append the formatted result of @p fmt and return @p
1147 s, which may have moved. Good for gradually accumulating output
1148 into a string buffer.
1150 char *talloc_asprintf_append(char *s
, const char *fmt
, ...)
1155 s
= talloc_vasprintf_append(s
, fmt
, ap
);
1161 alloc an array, checking for integer overflow in the array size
1163 void *_talloc_array(const void *ctx
, size_t el_size
, unsigned count
, const char *name
)
1165 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
1168 return talloc_named_const(ctx
, el_size
* count
, name
);
1172 alloc an zero array, checking for integer overflow in the array size
1174 void *_talloc_zero_array(const void *ctx
, size_t el_size
, unsigned count
, const char *name
)
1176 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
1179 return _talloc_zero(ctx
, el_size
* count
, name
);
1184 realloc an array, checking for integer overflow in the array size
1186 void *_talloc_realloc_array(const void *ctx
, void *ptr
, size_t el_size
, unsigned count
, const char *name
)
1188 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
1191 return _talloc_realloc(ctx
, ptr
, el_size
* count
, name
);
1195 a function version of talloc_realloc(), so it can be passed as a function pointer
1196 to libraries that want a realloc function (a realloc function encapsulates
1197 all the basic capabilities of an allocation library, which is why this is useful)
1199 void *talloc_realloc_fn(const void *context
, void *ptr
, size_t size
)
1201 return _talloc_realloc(context
, ptr
, size
, NULL
);
1205 static void talloc_autofree(void)
1207 talloc_free(cleanup_context
);
1208 cleanup_context
= NULL
;
1212 return a context which will be auto-freed on exit
1213 this is useful for reducing the noise in leak reports
1215 void *talloc_autofree_context(void)
1217 if (cleanup_context
== NULL
) {
1218 cleanup_context
= talloc_named_const(NULL
, 0, "autofree_context");
1219 atexit(talloc_autofree
);
1221 return cleanup_context
;
1224 size_t talloc_get_size(const void *context
)
1226 struct talloc_chunk
*tc
;
1228 if (context
== NULL
)
1231 tc
= talloc_chunk_from_ptr(context
);
1237 find a parent of this context that has the given name, if any
1239 void *talloc_find_parent_byname(const void *context
, const char *name
)
1241 struct talloc_chunk
*tc
;
1243 if (context
== NULL
) {
1247 tc
= talloc_chunk_from_ptr(context
);
1249 if (tc
->name
&& strcmp(tc
->name
, name
) == 0) {
1250 return TC_PTR_FROM_CHUNK(tc
);
1252 while (tc
&& tc
->prev
) tc
= tc
->prev
;
1259 show the parentage of a context
1261 void talloc_show_parents(const void *context
, FILE *file
)
1263 struct talloc_chunk
*tc
;
1265 if (context
== NULL
) {
1266 fprintf(file
, "talloc no parents for NULL\n");
1270 tc
= talloc_chunk_from_ptr(context
);
1271 fprintf(file
, "talloc parents of '%s'\n", talloc_get_name(context
));
1273 fprintf(file
, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc
)));
1274 while (tc
&& tc
->prev
) tc
= tc
->prev
;