blob: d3a0690fdb6344581afa062c2851eab54514ed3b [file] [log] [blame]
Harald Welteec8b4502010-02-20 20:34:29 +01001/*
2 Samba Unix SMB/CIFS implementation.
3
4 Samba trivial allocation library - new interface
5
6 NOTE: Please read talloc_guide.txt for full documentation
7
8 Copyright (C) Andrew Tridgell 2004
9 Copyright (C) Stefan Metzmacher 2006
10
11 ** NOTE! The following LGPL license applies to the talloc
12 ** library. This does NOT imply that all of Samba is released
13 ** under the LGPL
14
15 This library is free software; you can redistribute it and/or
16 modify it under the terms of the GNU Lesser General Public
17 License as published by the Free Software Foundation; either
18 version 3 of the License, or (at your option) any later version.
19
20 This library is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 Lesser General Public License for more details.
24
25 You should have received a copy of the GNU Lesser General Public
26 License along with this library; if not, see <http://www.gnu.org/licenses/>.
27*/
28
29/*
30 inspired by http://swapped.cc/halloc/
31*/
32
33#ifdef _SAMBA_BUILD_
34#include "version.h"
35#if (SAMBA_VERSION_MAJOR<4)
36#include "includes.h"
37/* This is to circumvent SAMBA3's paranoid malloc checker. Here in this file
38 * we trust ourselves... */
39#ifdef malloc
40#undef malloc
41#endif
42#ifdef realloc
43#undef realloc
44#endif
45#define _TALLOC_SAMBA3
46#endif /* (SAMBA_VERSION_MAJOR<4) */
47#endif /* _SAMBA_BUILD_ */
48
49#ifndef _TALLOC_SAMBA3
50//#include "replace.h"
Harald Welteec8b4502010-02-20 20:34:29 +010051#include <unistd.h>
52#include <stdio.h>
53#include <stdbool.h>
54#define __USE_GNU
55#include <string.h>
56#undef __USE_GNU
Pablo Neira Ayuso83419342011-03-22 16:36:13 +010057#include <osmocom/core/talloc.h>
Harald Welteec8b4502010-02-20 20:34:29 +010058#define MIN(x,y) ((x) < (y) ? (x) : (y))
59#endif /* not _TALLOC_SAMBA3 */
60
61/* use this to force every realloc to change the pointer, to stress test
62 code that might not cope */
63#define ALWAYS_REALLOC 0
64
65
66#define MAX_TALLOC_SIZE 0x10000000
67#define TALLOC_MAGIC 0xe814ec70
68#define TALLOC_FLAG_FREE 0x01
69#define TALLOC_FLAG_LOOP 0x02
70#define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */
71#define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */
72#define TALLOC_MAGIC_REFERENCE ((const char *)1)
73
74/* by default we abort when given a bad pointer (such as when talloc_free() is called
75 on a pointer that came from malloc() */
76#ifndef TALLOC_ABORT
77#define TALLOC_ABORT(reason) abort()
78#endif
79
80#ifndef discard_const_p
81#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
82# define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
83#else
84# define discard_const_p(type, ptr) ((type *)(ptr))
85#endif
86#endif
87
88/* these macros gain us a few percent of speed on gcc */
89#if (__GNUC__ >= 3)
90/* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
91 as its first argument */
92#ifndef likely
93#define likely(x) __builtin_expect(!!(x), 1)
94#endif
95#ifndef unlikely
96#define unlikely(x) __builtin_expect(!!(x), 0)
97#endif
98#else
99#ifndef likely
100#define likely(x) (x)
101#endif
102#ifndef unlikely
103#define unlikely(x) (x)
104#endif
105#endif
106
107#ifdef __APPLE__
108/* taken from http://insanecoding.blogspot.com/2007/03/methods-for-safe-string-handling.html */
109size_t strnlen(const char *s, size_t n)
110{
111 const char *p = (const char *)memchr(s, 0, n);
112 return(p ? p-s : n);
113}
114#endif
115
116/* this null_context is only used if talloc_enable_leak_report() or
117 talloc_enable_leak_report_full() is called, otherwise it remains
118 NULL
119*/
120static void *null_context;
121static void *autofree_context;
122
123struct talloc_reference_handle {
124 struct talloc_reference_handle *next, *prev;
125 void *ptr;
126};
127
128typedef int (*talloc_destructor_t)(void *);
129
130struct talloc_chunk {
131 struct talloc_chunk *next, *prev;
132 struct talloc_chunk *parent, *child;
133 struct talloc_reference_handle *refs;
134 talloc_destructor_t destructor;
135 const char *name;
136 size_t size;
137 unsigned flags;
138
139 /*
140 * "pool" has dual use:
141 *
142 * For the talloc pool itself (i.e. TALLOC_FLAG_POOL is set), "pool"
143 * marks the end of the currently allocated area.
144 *
145 * For members of the pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool"
146 * is a pointer to the struct talloc_chunk of the pool that it was
147 * allocated from. This way children can quickly find the pool to chew
148 * from.
149 */
150 void *pool;
151};
152
153/* 16 byte alignment seems to keep everyone happy */
154#define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
155#define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
156
157static void (*talloc_abort_fn)(const char *reason);
158
159void talloc_set_abort_fn(void (*abort_fn)(const char *reason))
160{
161 talloc_abort_fn = abort_fn;
162}
163
164static void talloc_abort(const char *reason)
165{
166 if (!talloc_abort_fn) {
167 TALLOC_ABORT(reason);
168 }
169
170 talloc_abort_fn(reason);
171}
172
173static void talloc_abort_double_free(void)
174{
175 talloc_abort("Bad talloc magic value - double free");
176}
177
178static void talloc_abort_unknown_value(void)
179{
180 talloc_abort("Bad talloc magic value - unknown value");
181}
182
183/* panic if we get a bad magic value */
184static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
185{
186 const char *pp = (const char *)ptr;
187 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
188 if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) {
189 if (tc->flags & TALLOC_FLAG_FREE) {
190 talloc_abort_double_free();
191 } else {
192 talloc_abort_unknown_value();
193 }
194 }
195 return tc;
196}
197
198/* hook into the front of the list */
199#define _TLIST_ADD(list, p) \
200do { \
201 if (!(list)) { \
202 (list) = (p); \
203 (p)->next = (p)->prev = NULL; \
204 } else { \
205 (list)->prev = (p); \
206 (p)->next = (list); \
207 (p)->prev = NULL; \
208 (list) = (p); \
209 }\
210} while (0)
211
212/* remove an element from a list - element doesn't have to be in list. */
213#define _TLIST_REMOVE(list, p) \
214do { \
215 if ((p) == (list)) { \
216 (list) = (p)->next; \
217 if (list) (list)->prev = NULL; \
218 } else { \
219 if ((p)->prev) (p)->prev->next = (p)->next; \
220 if ((p)->next) (p)->next->prev = (p)->prev; \
221 } \
222 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
223} while (0)
224
225
226/*
227 return the parent chunk of a pointer
228*/
229static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr)
230{
231 struct talloc_chunk *tc;
232
233 if (unlikely(ptr == NULL)) {
234 return NULL;
235 }
236
237 tc = talloc_chunk_from_ptr(ptr);
238 while (tc->prev) tc=tc->prev;
239
240 return tc->parent;
241}
242
243void *talloc_parent(const void *ptr)
244{
245 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
246 return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
247}
248
249/*
250 find parents name
251*/
252const char *talloc_parent_name(const void *ptr)
253{
254 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
255 return tc? tc->name : NULL;
256}
257
258/*
259 A pool carries an in-pool object count count in the first 16 bytes.
260 bytes. This is done to support talloc_steal() to a parent outside of the
261 pool. The count includes the pool itself, so a talloc_free() on a pool will
262 only destroy the pool if the count has dropped to zero. A talloc_free() of a
263 pool member will reduce the count, and eventually also call free(3) on the
264 pool memory.
265
266 The object count is not put into "struct talloc_chunk" because it is only
267 relevant for talloc pools and the alignment to 16 bytes would increase the
268 memory footprint of each talloc chunk by those 16 bytes.
269*/
270
271#define TALLOC_POOL_HDR_SIZE 16
272
273static unsigned int *talloc_pool_objectcount(struct talloc_chunk *tc)
274{
275 return (unsigned int *)((char *)tc + sizeof(struct talloc_chunk));
276}
277
278/*
279 Allocate from a pool
280*/
281
282static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
283 size_t size)
284{
285 struct talloc_chunk *pool_ctx = NULL;
286 size_t space_left;
287 struct talloc_chunk *result;
288 size_t chunk_size;
289
290 if (parent == NULL) {
291 return NULL;
292 }
293
294 if (parent->flags & TALLOC_FLAG_POOL) {
295 pool_ctx = parent;
296 }
297 else if (parent->flags & TALLOC_FLAG_POOLMEM) {
298 pool_ctx = (struct talloc_chunk *)parent->pool;
299 }
300
301 if (pool_ctx == NULL) {
302 return NULL;
303 }
304
305 space_left = ((char *)pool_ctx + TC_HDR_SIZE + pool_ctx->size)
306 - ((char *)pool_ctx->pool);
307
308 /*
309 * Align size to 16 bytes
310 */
311 chunk_size = ((size + 15) & ~15);
312
313 if (space_left < chunk_size) {
314 return NULL;
315 }
316
317 result = (struct talloc_chunk *)pool_ctx->pool;
318
319#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
320 VALGRIND_MAKE_MEM_UNDEFINED(result, size);
321#endif
322
323 pool_ctx->pool = (void *)((char *)result + chunk_size);
324
325 result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM;
326 result->pool = pool_ctx;
327
328 *talloc_pool_objectcount(pool_ctx) += 1;
329
330 return result;
331}
332
333/*
334 Allocate a bit of memory as a child of an existing pointer
335*/
336static inline void *__talloc(const void *context, size_t size)
337{
338 struct talloc_chunk *tc = NULL;
339
340 if (unlikely(context == NULL)) {
341 context = null_context;
342 }
343
344 if (unlikely(size >= MAX_TALLOC_SIZE)) {
345 return NULL;
346 }
347
348 if (context != NULL) {
349 tc = talloc_alloc_pool(talloc_chunk_from_ptr(context),
350 TC_HDR_SIZE+size);
351 }
352
353 if (tc == NULL) {
354 tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size);
355 if (unlikely(tc == NULL)) return NULL;
356 tc->flags = TALLOC_MAGIC;
357 tc->pool = NULL;
358 }
359
360 tc->size = size;
361 tc->destructor = NULL;
362 tc->child = NULL;
363 tc->name = NULL;
364 tc->refs = NULL;
365
366 if (likely(context)) {
367 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
368
369 if (parent->child) {
370 parent->child->parent = NULL;
371 tc->next = parent->child;
372 tc->next->prev = tc;
373 } else {
374 tc->next = NULL;
375 }
376 tc->parent = parent;
377 tc->prev = NULL;
378 parent->child = tc;
379 } else {
380 tc->next = tc->prev = tc->parent = NULL;
381 }
382
383 return TC_PTR_FROM_CHUNK(tc);
384}
385
386/*
387 * Create a talloc pool
388 */
389
390void *talloc_pool(const void *context, size_t size)
391{
392 void *result = __talloc(context, size + TALLOC_POOL_HDR_SIZE);
393 struct talloc_chunk *tc;
394
395 if (unlikely(result == NULL)) {
396 return NULL;
397 }
398
399 tc = talloc_chunk_from_ptr(result);
400
401 tc->flags |= TALLOC_FLAG_POOL;
402 tc->pool = (char *)result + TALLOC_POOL_HDR_SIZE;
403
404 *talloc_pool_objectcount(tc) = 1;
405
406#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
407 VALGRIND_MAKE_MEM_NOACCESS(tc->pool, size);
408#endif
409
410 return result;
411}
412
413/*
414 setup a destructor to be called on free of a pointer
415 the destructor should return 0 on success, or -1 on failure.
416 if the destructor fails then the free is failed, and the memory can
417 be continued to be used
418*/
419void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
420{
421 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
422 tc->destructor = destructor;
423}
424
425/*
426 increase the reference count on a piece of memory.
427*/
428int talloc_increase_ref_count(const void *ptr)
429{
430 if (unlikely(!talloc_reference(null_context, ptr))) {
431 return -1;
432 }
433 return 0;
434}
435
436/*
437 helper for talloc_reference()
438
439 this is referenced by a function pointer and should not be inline
440*/
441static int talloc_reference_destructor(struct talloc_reference_handle *handle)
442{
443 struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
444 _TLIST_REMOVE(ptr_tc->refs, handle);
445 return 0;
446}
447
448/*
449 more efficient way to add a name to a pointer - the name must point to a
450 true string constant
451*/
452static inline void _talloc_set_name_const(const void *ptr, const char *name)
453{
454 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
455 tc->name = name;
456}
457
458/*
459 internal talloc_named_const()
460*/
461static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
462{
463 void *ptr;
464
465 ptr = __talloc(context, size);
466 if (unlikely(ptr == NULL)) {
467 return NULL;
468 }
469
470 _talloc_set_name_const(ptr, name);
471
472 return ptr;
473}
474
475/*
476 make a secondary reference to a pointer, hanging off the given context.
477 the pointer remains valid until both the original caller and this given
478 context are freed.
479
480 the major use for this is when two different structures need to reference the
481 same underlying data, and you want to be able to free the two instances separately,
482 and in either order
483*/
484void *_talloc_reference(const void *context, const void *ptr)
485{
486 struct talloc_chunk *tc;
487 struct talloc_reference_handle *handle;
488 if (unlikely(ptr == NULL)) return NULL;
489
490 tc = talloc_chunk_from_ptr(ptr);
491 handle = (struct talloc_reference_handle *)_talloc_named_const(context,
492 sizeof(struct talloc_reference_handle),
493 TALLOC_MAGIC_REFERENCE);
494 if (unlikely(handle == NULL)) return NULL;
495
496 /* note that we hang the destructor off the handle, not the
497 main context as that allows the caller to still setup their
498 own destructor on the context if they want to */
499 talloc_set_destructor(handle, talloc_reference_destructor);
500 handle->ptr = discard_const_p(void, ptr);
501 _TLIST_ADD(tc->refs, handle);
502 return handle->ptr;
503}
504
505
506/*
507 internal talloc_free call
508*/
509static inline int _talloc_free(void *ptr)
510{
511 struct talloc_chunk *tc;
512
513 if (unlikely(ptr == NULL)) {
514 return -1;
515 }
516
517 tc = talloc_chunk_from_ptr(ptr);
518
519 if (unlikely(tc->refs)) {
520 int is_child;
521 /* check this is a reference from a child or grantchild
522 * back to it's parent or grantparent
523 *
524 * in that case we need to remove the reference and
525 * call another instance of talloc_free() on the current
526 * pointer.
527 */
528 is_child = talloc_is_parent(tc->refs, ptr);
529 _talloc_free(tc->refs);
530 if (is_child) {
531 return _talloc_free(ptr);
532 }
533 return -1;
534 }
535
536 if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
537 /* we have a free loop - stop looping */
538 return 0;
539 }
540
541 if (unlikely(tc->destructor)) {
542 talloc_destructor_t d = tc->destructor;
543 if (d == (talloc_destructor_t)-1) {
544 return -1;
545 }
546 tc->destructor = (talloc_destructor_t)-1;
547 if (d(ptr) == -1) {
548 tc->destructor = d;
549 return -1;
550 }
551 tc->destructor = NULL;
552 }
553
554 if (tc->parent) {
555 _TLIST_REMOVE(tc->parent->child, tc);
556 if (tc->parent->child) {
557 tc->parent->child->parent = tc->parent;
558 }
559 } else {
560 if (tc->prev) tc->prev->next = tc->next;
561 if (tc->next) tc->next->prev = tc->prev;
562 }
563
564 tc->flags |= TALLOC_FLAG_LOOP;
565
566 while (tc->child) {
567 /* we need to work out who will own an abandoned child
568 if it cannot be freed. In priority order, the first
569 choice is owner of any remaining reference to this
570 pointer, the second choice is our parent, and the
571 final choice is the null context. */
572 void *child = TC_PTR_FROM_CHUNK(tc->child);
573 const void *new_parent = null_context;
574 if (unlikely(tc->child->refs)) {
575 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
576 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
577 }
578 if (unlikely(_talloc_free(child) == -1)) {
579 if (new_parent == null_context) {
580 struct talloc_chunk *p = talloc_parent_chunk(ptr);
581 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
582 }
583 talloc_steal(new_parent, child);
584 }
585 }
586
587 tc->flags |= TALLOC_FLAG_FREE;
588
589 if (tc->flags & (TALLOC_FLAG_POOL|TALLOC_FLAG_POOLMEM)) {
590 struct talloc_chunk *pool;
591 unsigned int *pool_object_count;
592
593 pool = (tc->flags & TALLOC_FLAG_POOL)
594 ? tc : (struct talloc_chunk *)tc->pool;
595
596 pool_object_count = talloc_pool_objectcount(pool);
597
598 if (*pool_object_count == 0) {
599 talloc_abort("Pool object count zero!");
600 }
601
602 *pool_object_count -= 1;
603
604 if (*pool_object_count == 0) {
605 free(pool);
606 }
607 }
608 else {
609 free(tc);
610 }
611 return 0;
612}
613
614/*
615 move a lump of memory from one talloc context to another return the
616 ptr on success, or NULL if it could not be transferred.
617 passing NULL as ptr will always return NULL with no side effects.
618*/
619void *_talloc_steal(const void *new_ctx, const void *ptr)
620{
621 struct talloc_chunk *tc, *new_tc;
622
623 if (unlikely(!ptr)) {
624 return NULL;
625 }
626
627 if (unlikely(new_ctx == NULL)) {
628 new_ctx = null_context;
629 }
630
631 tc = talloc_chunk_from_ptr(ptr);
632
633 if (unlikely(new_ctx == NULL)) {
634 if (tc->parent) {
635 _TLIST_REMOVE(tc->parent->child, tc);
636 if (tc->parent->child) {
637 tc->parent->child->parent = tc->parent;
638 }
639 } else {
640 if (tc->prev) tc->prev->next = tc->next;
641 if (tc->next) tc->next->prev = tc->prev;
642 }
643
644 tc->parent = tc->next = tc->prev = NULL;
645 return discard_const_p(void, ptr);
646 }
647
648 new_tc = talloc_chunk_from_ptr(new_ctx);
649
650 if (unlikely(tc == new_tc || tc->parent == new_tc)) {
651 return discard_const_p(void, ptr);
652 }
653
654 if (tc->parent) {
655 _TLIST_REMOVE(tc->parent->child, tc);
656 if (tc->parent->child) {
657 tc->parent->child->parent = tc->parent;
658 }
659 } else {
660 if (tc->prev) tc->prev->next = tc->next;
661 if (tc->next) tc->next->prev = tc->prev;
662 }
663
664 tc->parent = new_tc;
665 if (new_tc->child) new_tc->child->parent = NULL;
666 _TLIST_ADD(new_tc->child, tc);
667
668 return discard_const_p(void, ptr);
669}
670
671
672
673/*
674 remove a secondary reference to a pointer. This undo's what
675 talloc_reference() has done. The context and pointer arguments
676 must match those given to a talloc_reference()
677*/
678static inline int talloc_unreference(const void *context, const void *ptr)
679{
680 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
681 struct talloc_reference_handle *h;
682
683 if (unlikely(context == NULL)) {
684 context = null_context;
685 }
686
687 for (h=tc->refs;h;h=h->next) {
688 struct talloc_chunk *p = talloc_parent_chunk(h);
689 if (p == NULL) {
690 if (context == NULL) break;
691 } else if (TC_PTR_FROM_CHUNK(p) == context) {
692 break;
693 }
694 }
695 if (h == NULL) {
696 return -1;
697 }
698
699 return _talloc_free(h);
700}
701
702/*
703 remove a specific parent context from a pointer. This is a more
704 controlled varient of talloc_free()
705*/
706int talloc_unlink(const void *context, void *ptr)
707{
708 struct talloc_chunk *tc_p, *new_p;
709 void *new_parent;
710
711 if (ptr == NULL) {
712 return -1;
713 }
714
715 if (context == NULL) {
716 context = null_context;
717 }
718
719 if (talloc_unreference(context, ptr) == 0) {
720 return 0;
721 }
722
723 if (context == NULL) {
724 if (talloc_parent_chunk(ptr) != NULL) {
725 return -1;
726 }
727 } else {
728 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
729 return -1;
730 }
731 }
732
733 tc_p = talloc_chunk_from_ptr(ptr);
734
735 if (tc_p->refs == NULL) {
736 return _talloc_free(ptr);
737 }
738
739 new_p = talloc_parent_chunk(tc_p->refs);
740 if (new_p) {
741 new_parent = TC_PTR_FROM_CHUNK(new_p);
742 } else {
743 new_parent = NULL;
744 }
745
746 if (talloc_unreference(new_parent, ptr) != 0) {
747 return -1;
748 }
749
750 talloc_steal(new_parent, ptr);
751
752 return 0;
753}
754
755/*
756 add a name to an existing pointer - va_list version
757*/
758static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
759
760static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
761{
762 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
763 tc->name = talloc_vasprintf(ptr, fmt, ap);
764 if (likely(tc->name)) {
765 _talloc_set_name_const(tc->name, ".name");
766 }
767 return tc->name;
768}
769
770/*
771 add a name to an existing pointer
772*/
773const char *talloc_set_name(const void *ptr, const char *fmt, ...)
774{
775 const char *name;
776 va_list ap;
777 va_start(ap, fmt);
778 name = talloc_set_name_v(ptr, fmt, ap);
779 va_end(ap);
780 return name;
781}
782
783
784/*
785 create a named talloc pointer. Any talloc pointer can be named, and
786 talloc_named() operates just like talloc() except that it allows you
787 to name the pointer.
788*/
789void *talloc_named(const void *context, size_t size, const char *fmt, ...)
790{
791 va_list ap;
792 void *ptr;
793 const char *name;
794
795 ptr = __talloc(context, size);
796 if (unlikely(ptr == NULL)) return NULL;
797
798 va_start(ap, fmt);
799 name = talloc_set_name_v(ptr, fmt, ap);
800 va_end(ap);
801
802 if (unlikely(name == NULL)) {
803 _talloc_free(ptr);
804 return NULL;
805 }
806
807 return ptr;
808}
809
810/*
811 return the name of a talloc ptr, or "UNNAMED"
812*/
813const char *talloc_get_name(const void *ptr)
814{
815 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
816 if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
817 return ".reference";
818 }
819 if (likely(tc->name)) {
820 return tc->name;
821 }
822 return "UNNAMED";
823}
824
825
826/*
827 check if a pointer has the given name. If it does, return the pointer,
828 otherwise return NULL
829*/
830void *talloc_check_name(const void *ptr, const char *name)
831{
832 const char *pname;
833 if (unlikely(ptr == NULL)) return NULL;
834 pname = talloc_get_name(ptr);
835 if (likely(pname == name || strcmp(pname, name) == 0)) {
836 return discard_const_p(void, ptr);
837 }
838 return NULL;
839}
840
841static void talloc_abort_type_missmatch(const char *location,
842 const char *name,
843 const char *expected)
844{
845 const char *reason;
846
847 reason = talloc_asprintf(NULL,
848 "%s: Type mismatch: name[%s] expected[%s]",
849 location,
850 name?name:"NULL",
851 expected);
852 if (!reason) {
853 reason = "Type mismatch";
854 }
855
856 talloc_abort(reason);
857}
858
859void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location)
860{
861 const char *pname;
862
863 if (unlikely(ptr == NULL)) {
864 talloc_abort_type_missmatch(location, NULL, name);
865 return NULL;
866 }
867
868 pname = talloc_get_name(ptr);
869 if (likely(pname == name || strcmp(pname, name) == 0)) {
870 return discard_const_p(void, ptr);
871 }
872
873 talloc_abort_type_missmatch(location, pname, name);
874 return NULL;
875}
876
877/*
878 this is for compatibility with older versions of talloc
879*/
880void *talloc_init(const char *fmt, ...)
881{
882 va_list ap;
883 void *ptr;
884 const char *name;
885
886 /*
887 * samba3 expects talloc_report_depth_cb(NULL, ...)
888 * reports all talloc'ed memory, so we need to enable
889 * null_tracking
890 */
891 talloc_enable_null_tracking();
892
893 ptr = __talloc(NULL, 0);
894 if (unlikely(ptr == NULL)) return NULL;
895
896 va_start(ap, fmt);
897 name = talloc_set_name_v(ptr, fmt, ap);
898 va_end(ap);
899
900 if (unlikely(name == NULL)) {
901 _talloc_free(ptr);
902 return NULL;
903 }
904
905 return ptr;
906}
907
908/*
909 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
910 should probably not be used in new code. It's in here to keep the talloc
911 code consistent across Samba 3 and 4.
912*/
913void talloc_free_children(void *ptr)
914{
915 struct talloc_chunk *tc;
916
917 if (unlikely(ptr == NULL)) {
918 return;
919 }
920
921 tc = talloc_chunk_from_ptr(ptr);
922
923 while (tc->child) {
924 /* we need to work out who will own an abandoned child
925 if it cannot be freed. In priority order, the first
926 choice is owner of any remaining reference to this
927 pointer, the second choice is our parent, and the
928 final choice is the null context. */
929 void *child = TC_PTR_FROM_CHUNK(tc->child);
930 const void *new_parent = null_context;
931 if (unlikely(tc->child->refs)) {
932 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
933 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
934 }
935 if (unlikely(_talloc_free(child) == -1)) {
936 if (new_parent == null_context) {
937 struct talloc_chunk *p = talloc_parent_chunk(ptr);
938 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
939 }
940 talloc_steal(new_parent, child);
941 }
942 }
943
944 if ((tc->flags & TALLOC_FLAG_POOL)
945 && (*talloc_pool_objectcount(tc) == 1)) {
946 tc->pool = ((char *)tc + TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE);
947#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
948 VALGRIND_MAKE_MEM_NOACCESS(
949 tc->pool, tc->size - TALLOC_POOL_HDR_SIZE);
950#endif
951 }
952}
953
954/*
955 Allocate a bit of memory as a child of an existing pointer
956*/
957void *_talloc(const void *context, size_t size)
958{
959 return __talloc(context, size);
960}
961
962/*
963 externally callable talloc_set_name_const()
964*/
965void talloc_set_name_const(const void *ptr, const char *name)
966{
967 _talloc_set_name_const(ptr, name);
968}
969
970/*
971 create a named talloc pointer. Any talloc pointer can be named, and
972 talloc_named() operates just like talloc() except that it allows you
973 to name the pointer.
974*/
975void *talloc_named_const(const void *context, size_t size, const char *name)
976{
977 return _talloc_named_const(context, size, name);
978}
979
980/*
981 free a talloc pointer. This also frees all child pointers of this
982 pointer recursively
983
984 return 0 if the memory is actually freed, otherwise -1. The memory
985 will not be freed if the ref_count is > 1 or the destructor (if
986 any) returns non-zero
987*/
988int talloc_free(void *ptr)
989{
990 return _talloc_free(ptr);
991}
992
993
994
995/*
996 A talloc version of realloc. The context argument is only used if
997 ptr is NULL
998*/
999void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
1000{
1001 struct talloc_chunk *tc;
1002 void *new_ptr;
1003 bool malloced = false;
1004
1005 /* size zero is equivalent to free() */
1006 if (unlikely(size == 0)) {
1007 _talloc_free(ptr);
1008 return NULL;
1009 }
1010
1011 if (unlikely(size >= MAX_TALLOC_SIZE)) {
1012 return NULL;
1013 }
1014
1015 /* realloc(NULL) is equivalent to malloc() */
1016 if (ptr == NULL) {
1017 return _talloc_named_const(context, size, name);
1018 }
1019
1020 tc = talloc_chunk_from_ptr(ptr);
1021
1022 /* don't allow realloc on referenced pointers */
1023 if (unlikely(tc->refs)) {
1024 return NULL;
1025 }
1026
1027 /* don't let anybody try to realloc a talloc_pool */
1028 if (unlikely(tc->flags & TALLOC_FLAG_POOL)) {
1029 return NULL;
1030 }
1031
1032 /* don't shrink if we have less than 1k to gain */
1033 if ((size < tc->size) && ((tc->size - size) < 1024)) {
1034 tc->size = size;
1035 return ptr;
1036 }
1037
1038 /* by resetting magic we catch users of the old memory */
1039 tc->flags |= TALLOC_FLAG_FREE;
1040
1041#if ALWAYS_REALLOC
1042 new_ptr = malloc(size + TC_HDR_SIZE);
1043 if (new_ptr) {
1044 memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
1045 free(tc);
1046 }
1047#else
1048 if (tc->flags & TALLOC_FLAG_POOLMEM) {
1049
1050 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE);
1051 *talloc_pool_objectcount((struct talloc_chunk *)
1052 (tc->pool)) -= 1;
1053
1054 if (new_ptr == NULL) {
1055 new_ptr = malloc(TC_HDR_SIZE+size);
1056 malloced = true;
1057 }
1058
1059 if (new_ptr) {
1060 memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
1061 }
1062 }
1063 else {
1064 new_ptr = realloc(tc, size + TC_HDR_SIZE);
1065 }
1066#endif
1067 if (unlikely(!new_ptr)) {
1068 tc->flags &= ~TALLOC_FLAG_FREE;
1069 return NULL;
1070 }
1071
1072 tc = (struct talloc_chunk *)new_ptr;
1073 tc->flags &= ~TALLOC_FLAG_FREE;
1074 if (malloced) {
1075 tc->flags &= ~TALLOC_FLAG_POOLMEM;
1076 }
1077 if (tc->parent) {
1078 tc->parent->child = tc;
1079 }
1080 if (tc->child) {
1081 tc->child->parent = tc;
1082 }
1083
1084 if (tc->prev) {
1085 tc->prev->next = tc;
1086 }
1087 if (tc->next) {
1088 tc->next->prev = tc;
1089 }
1090
1091 tc->size = size;
1092 _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
1093
1094 return TC_PTR_FROM_CHUNK(tc);
1095}
1096
1097/*
1098 a wrapper around talloc_steal() for situations where you are moving a pointer
1099 between two structures, and want the old pointer to be set to NULL
1100*/
1101void *_talloc_move(const void *new_ctx, const void *_pptr)
1102{
1103 const void **pptr = discard_const_p(const void *,_pptr);
1104 void *ret = _talloc_steal(new_ctx, *pptr);
1105 (*pptr) = NULL;
1106 return ret;
1107}
1108
1109/*
1110 return the total size of a talloc pool (subtree)
1111*/
1112size_t talloc_total_size(const void *ptr)
1113{
1114 size_t total = 0;
1115 struct talloc_chunk *c, *tc;
1116
1117 if (ptr == NULL) {
1118 ptr = null_context;
1119 }
1120 if (ptr == NULL) {
1121 return 0;
1122 }
1123
1124 tc = talloc_chunk_from_ptr(ptr);
1125
1126 if (tc->flags & TALLOC_FLAG_LOOP) {
1127 return 0;
1128 }
1129
1130 tc->flags |= TALLOC_FLAG_LOOP;
1131
1132 total = tc->size;
1133 for (c=tc->child;c;c=c->next) {
1134 total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
1135 }
1136
1137 tc->flags &= ~TALLOC_FLAG_LOOP;
1138
1139 return total;
1140}
1141
1142/*
1143 return the total number of blocks in a talloc pool (subtree)
1144*/
1145size_t talloc_total_blocks(const void *ptr)
1146{
1147 size_t total = 0;
1148 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
1149
1150 if (tc->flags & TALLOC_FLAG_LOOP) {
1151 return 0;
1152 }
1153
1154 tc->flags |= TALLOC_FLAG_LOOP;
1155
1156 total++;
1157 for (c=tc->child;c;c=c->next) {
1158 total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
1159 }
1160
1161 tc->flags &= ~TALLOC_FLAG_LOOP;
1162
1163 return total;
1164}
1165
1166/*
1167 return the number of external references to a pointer
1168*/
1169size_t talloc_reference_count(const void *ptr)
1170{
1171 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1172 struct talloc_reference_handle *h;
1173 size_t ret = 0;
1174
1175 for (h=tc->refs;h;h=h->next) {
1176 ret++;
1177 }
1178 return ret;
1179}
1180
1181/*
1182 report on memory usage by all children of a pointer, giving a full tree view
1183*/
1184void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1185 void (*callback)(const void *ptr,
1186 int depth, int max_depth,
1187 int is_ref,
1188 void *private_data),
1189 void *private_data)
1190{
1191 struct talloc_chunk *c, *tc;
1192
1193 if (ptr == NULL) {
1194 ptr = null_context;
1195 }
1196 if (ptr == NULL) return;
1197
1198 tc = talloc_chunk_from_ptr(ptr);
1199
1200 if (tc->flags & TALLOC_FLAG_LOOP) {
1201 return;
1202 }
1203
1204 callback(ptr, depth, max_depth, 0, private_data);
1205
1206 if (max_depth >= 0 && depth >= max_depth) {
1207 return;
1208 }
1209
1210 tc->flags |= TALLOC_FLAG_LOOP;
1211 for (c=tc->child;c;c=c->next) {
1212 if (c->name == TALLOC_MAGIC_REFERENCE) {
1213 struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
1214 callback(h->ptr, depth + 1, max_depth, 1, private_data);
1215 } else {
1216 talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
1217 }
1218 }
1219 tc->flags &= ~TALLOC_FLAG_LOOP;
1220}
1221
1222static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
1223{
1224 const char *name = talloc_get_name(ptr);
1225 FILE *f = (FILE *)_f;
1226
1227 if (is_ref) {
1228 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
1229 return;
1230 }
1231
1232 if (depth == 0) {
1233 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
1234 (max_depth < 0 ? "full " :""), name,
1235 (unsigned long)talloc_total_size(ptr),
1236 (unsigned long)talloc_total_blocks(ptr));
1237 return;
1238 }
1239
1240 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
1241 depth*4, "",
1242 name,
1243 (unsigned long)talloc_total_size(ptr),
1244 (unsigned long)talloc_total_blocks(ptr),
1245 (int)talloc_reference_count(ptr), ptr);
1246
1247#if 0
1248 fprintf(f, "content: ");
1249 if (talloc_total_size(ptr)) {
1250 int tot = talloc_total_size(ptr);
1251 int i;
1252
1253 for (i = 0; i < tot; i++) {
1254 if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
1255 fprintf(f, "%c", ((char *)ptr)[i]);
1256 } else {
1257 fprintf(f, "~%02x", ((char *)ptr)[i]);
1258 }
1259 }
1260 }
1261 fprintf(f, "\n");
1262#endif
1263}
1264
1265/*
1266 report on memory usage by all children of a pointer, giving a full tree view
1267*/
1268void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
1269{
1270 talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
1271 fflush(f);
1272}
1273
1274/*
1275 report on memory usage by all children of a pointer, giving a full tree view
1276*/
1277void talloc_report_full(const void *ptr, FILE *f)
1278{
1279 talloc_report_depth_file(ptr, 0, -1, f);
1280}
1281
1282/*
1283 report on memory usage by all children of a pointer
1284*/
1285void talloc_report(const void *ptr, FILE *f)
1286{
1287 talloc_report_depth_file(ptr, 0, 1, f);
1288}
1289
1290/*
1291 report on any memory hanging off the null context
1292*/
1293static void talloc_report_null(void)
1294{
1295 if (talloc_total_size(null_context) != 0) {
1296 talloc_report(null_context, stderr);
1297 }
1298}
1299
1300/*
1301 report on any memory hanging off the null context
1302*/
1303static void talloc_report_null_full(void)
1304{
1305 if (talloc_total_size(null_context) != 0) {
1306 talloc_report_full(null_context, stderr);
1307 }
1308}
1309
1310/*
1311 enable tracking of the NULL context
1312*/
1313void talloc_enable_null_tracking(void)
1314{
1315 if (null_context == NULL) {
1316 null_context = _talloc_named_const(NULL, 0, "null_context");
1317 }
1318}
1319
1320/*
1321 disable tracking of the NULL context
1322*/
1323void talloc_disable_null_tracking(void)
1324{
1325 _talloc_free(null_context);
1326 null_context = NULL;
1327}
1328
1329/*
1330 enable leak reporting on exit
1331*/
1332void talloc_enable_leak_report(void)
1333{
1334 talloc_enable_null_tracking();
1335 atexit(talloc_report_null);
1336}
1337
1338/*
1339 enable full leak reporting on exit
1340*/
1341void talloc_enable_leak_report_full(void)
1342{
1343 talloc_enable_null_tracking();
1344 atexit(talloc_report_null_full);
1345}
1346
1347/*
1348 talloc and zero memory.
1349*/
1350void *_talloc_zero(const void *ctx, size_t size, const char *name)
1351{
1352 void *p = _talloc_named_const(ctx, size, name);
1353
1354 if (p) {
1355 memset(p, '\0', size);
1356 }
1357
1358 return p;
1359}
1360
1361/*
1362 memdup with a talloc.
1363*/
1364void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
1365{
1366 void *newp = _talloc_named_const(t, size, name);
1367
1368 if (likely(newp)) {
1369 memcpy(newp, p, size);
1370 }
1371
1372 return newp;
1373}
1374
1375static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
1376{
1377 char *ret;
1378
1379 ret = (char *)__talloc(t, len + 1);
1380 if (unlikely(!ret)) return NULL;
1381
1382 memcpy(ret, p, len);
1383 ret[len] = 0;
1384
1385 _talloc_set_name_const(ret, ret);
1386 return ret;
1387}
1388
1389/*
1390 strdup with a talloc
1391*/
1392char *talloc_strdup(const void *t, const char *p)
1393{
1394 if (unlikely(!p)) return NULL;
1395 return __talloc_strlendup(t, p, strlen(p));
1396}
1397
1398/*
1399 strndup with a talloc
1400*/
1401char *talloc_strndup(const void *t, const char *p, size_t n)
1402{
1403 if (unlikely(!p)) return NULL;
1404 return __talloc_strlendup(t, p, strnlen(p, n));
1405}
1406
1407static inline char *__talloc_strlendup_append(char *s, size_t slen,
1408 const char *a, size_t alen)
1409{
1410 char *ret;
1411
1412 ret = talloc_realloc(NULL, s, char, slen + alen + 1);
1413 if (unlikely(!ret)) return NULL;
1414
1415 /* append the string and the trailing \0 */
1416 memcpy(&ret[slen], a, alen);
1417 ret[slen+alen] = 0;
1418
1419 _talloc_set_name_const(ret, ret);
1420 return ret;
1421}
1422
1423/*
1424 * Appends at the end of the string.
1425 */
1426char *talloc_strdup_append(char *s, const char *a)
1427{
1428 if (unlikely(!s)) {
1429 return talloc_strdup(NULL, a);
1430 }
1431
1432 if (unlikely(!a)) {
1433 return s;
1434 }
1435
1436 return __talloc_strlendup_append(s, strlen(s), a, strlen(a));
1437}
1438
1439/*
1440 * Appends at the end of the talloc'ed buffer,
1441 * not the end of the string.
1442 */
1443char *talloc_strdup_append_buffer(char *s, const char *a)
1444{
1445 size_t slen;
1446
1447 if (unlikely(!s)) {
1448 return talloc_strdup(NULL, a);
1449 }
1450
1451 if (unlikely(!a)) {
1452 return s;
1453 }
1454
1455 slen = talloc_get_size(s);
1456 if (likely(slen > 0)) {
1457 slen--;
1458 }
1459
1460 return __talloc_strlendup_append(s, slen, a, strlen(a));
1461}
1462
1463/*
1464 * Appends at the end of the string.
1465 */
1466char *talloc_strndup_append(char *s, const char *a, size_t n)
1467{
1468 if (unlikely(!s)) {
1469 return talloc_strdup(NULL, a);
1470 }
1471
1472 if (unlikely(!a)) {
1473 return s;
1474 }
1475
1476 return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n));
1477}
1478
1479/*
1480 * Appends at the end of the talloc'ed buffer,
1481 * not the end of the string.
1482 */
1483char *talloc_strndup_append_buffer(char *s, const char *a, size_t n)
1484{
1485 size_t slen;
1486
1487 if (unlikely(!s)) {
1488 return talloc_strdup(NULL, a);
1489 }
1490
1491 if (unlikely(!a)) {
1492 return s;
1493 }
1494
1495 slen = talloc_get_size(s);
1496 if (likely(slen > 0)) {
1497 slen--;
1498 }
1499
1500 return __talloc_strlendup_append(s, slen, a, strnlen(a, n));
1501}
1502
1503#ifndef HAVE_VA_COPY
1504#ifdef HAVE___VA_COPY
1505#define va_copy(dest, src) __va_copy(dest, src)
1506#else
1507#define va_copy(dest, src) (dest) = (src)
1508#endif
1509#endif
1510
1511char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1512{
1513 int len;
1514 char *ret;
1515 va_list ap2;
1516 char c;
1517
1518 /* this call looks strange, but it makes it work on older solaris boxes */
1519 va_copy(ap2, ap);
1520 len = vsnprintf(&c, 1, fmt, ap2);
1521 va_end(ap2);
1522 if (unlikely(len < 0)) {
1523 return NULL;
1524 }
1525
1526 ret = (char *)__talloc(t, len+1);
1527 if (unlikely(!ret)) return NULL;
1528
1529 va_copy(ap2, ap);
1530 vsnprintf(ret, len+1, fmt, ap2);
1531 va_end(ap2);
1532
1533 _talloc_set_name_const(ret, ret);
1534 return ret;
1535}
1536
1537
1538/*
1539 Perform string formatting, and return a pointer to newly allocated
1540 memory holding the result, inside a memory pool.
1541 */
1542char *talloc_asprintf(const void *t, const char *fmt, ...)
1543{
1544 va_list ap;
1545 char *ret;
1546
1547 va_start(ap, fmt);
1548 ret = talloc_vasprintf(t, fmt, ap);
1549 va_end(ap);
1550 return ret;
1551}
1552
1553static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1554 const char *fmt, va_list ap)
1555 PRINTF_ATTRIBUTE(3,0);
1556
1557static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1558 const char *fmt, va_list ap)
1559{
1560 ssize_t alen;
1561 va_list ap2;
1562 char c;
1563
1564 va_copy(ap2, ap);
1565 alen = vsnprintf(&c, 1, fmt, ap2);
1566 va_end(ap2);
1567
1568 if (alen <= 0) {
1569 /* Either the vsnprintf failed or the format resulted in
1570 * no characters being formatted. In the former case, we
1571 * ought to return NULL, in the latter we ought to return
1572 * the original string. Most current callers of this
1573 * function expect it to never return NULL.
1574 */
1575 return s;
1576 }
1577
1578 s = talloc_realloc(NULL, s, char, slen + alen + 1);
1579 if (!s) return NULL;
1580
1581 va_copy(ap2, ap);
1582 vsnprintf(s + slen, alen + 1, fmt, ap2);
1583 va_end(ap2);
1584
1585 _talloc_set_name_const(s, s);
1586 return s;
1587}
1588
1589/**
1590 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1591 * and return @p s, which may have moved. Good for gradually
1592 * accumulating output into a string buffer. Appends at the end
1593 * of the string.
1594 **/
1595char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1596{
1597 if (unlikely(!s)) {
1598 return talloc_vasprintf(NULL, fmt, ap);
1599 }
1600
1601 return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap);
1602}
1603
1604/**
1605 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1606 * and return @p s, which may have moved. Always appends at the
1607 * end of the talloc'ed buffer, not the end of the string.
1608 **/
1609char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap)
1610{
1611 size_t slen;
1612
1613 if (unlikely(!s)) {
1614 return talloc_vasprintf(NULL, fmt, ap);
1615 }
1616
1617 slen = talloc_get_size(s);
1618 if (likely(slen > 0)) {
1619 slen--;
1620 }
1621
1622 return __talloc_vaslenprintf_append(s, slen, fmt, ap);
1623}
1624
1625/*
1626 Realloc @p s to append the formatted result of @p fmt and return @p
1627 s, which may have moved. Good for gradually accumulating output
1628 into a string buffer.
1629 */
1630char *talloc_asprintf_append(char *s, const char *fmt, ...)
1631{
1632 va_list ap;
1633
1634 va_start(ap, fmt);
1635 s = talloc_vasprintf_append(s, fmt, ap);
1636 va_end(ap);
1637 return s;
1638}
1639
1640/*
1641 Realloc @p s to append the formatted result of @p fmt and return @p
1642 s, which may have moved. Good for gradually accumulating output
1643 into a buffer.
1644 */
1645char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...)
1646{
1647 va_list ap;
1648
1649 va_start(ap, fmt);
1650 s = talloc_vasprintf_append_buffer(s, fmt, ap);
1651 va_end(ap);
1652 return s;
1653}
1654
1655/*
1656 alloc an array, checking for integer overflow in the array size
1657*/
1658void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1659{
1660 if (count >= MAX_TALLOC_SIZE/el_size) {
1661 return NULL;
1662 }
1663 return _talloc_named_const(ctx, el_size * count, name);
1664}
1665
1666/*
1667 alloc an zero array, checking for integer overflow in the array size
1668*/
1669void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1670{
1671 if (count >= MAX_TALLOC_SIZE/el_size) {
1672 return NULL;
1673 }
1674 return _talloc_zero(ctx, el_size * count, name);
1675}
1676
1677/*
1678 realloc an array, checking for integer overflow in the array size
1679*/
1680void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1681{
1682 if (count >= MAX_TALLOC_SIZE/el_size) {
1683 return NULL;
1684 }
1685 return _talloc_realloc(ctx, ptr, el_size * count, name);
1686}
1687
1688/*
1689 a function version of talloc_realloc(), so it can be passed as a function pointer
1690 to libraries that want a realloc function (a realloc function encapsulates
1691 all the basic capabilities of an allocation library, which is why this is useful)
1692*/
1693void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1694{
1695 return _talloc_realloc(context, ptr, size, NULL);
1696}
1697
1698
1699static int talloc_autofree_destructor(void *ptr)
1700{
1701 autofree_context = NULL;
1702 return 0;
1703}
1704
1705static void talloc_autofree(void)
1706{
1707 _talloc_free(autofree_context);
1708}
1709
1710/*
1711 return a context which will be auto-freed on exit
1712 this is useful for reducing the noise in leak reports
1713*/
1714void *talloc_autofree_context(void)
1715{
1716 if (autofree_context == NULL) {
1717 autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
1718 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
1719 atexit(talloc_autofree);
1720 }
1721 return autofree_context;
1722}
1723
1724size_t talloc_get_size(const void *context)
1725{
1726 struct talloc_chunk *tc;
1727
1728 if (context == NULL)
1729 return 0;
1730
1731 tc = talloc_chunk_from_ptr(context);
1732
1733 return tc->size;
1734}
1735
1736/*
1737 find a parent of this context that has the given name, if any
1738*/
1739void *talloc_find_parent_byname(const void *context, const char *name)
1740{
1741 struct talloc_chunk *tc;
1742
1743 if (context == NULL) {
1744 return NULL;
1745 }
1746
1747 tc = talloc_chunk_from_ptr(context);
1748 while (tc) {
1749 if (tc->name && strcmp(tc->name, name) == 0) {
1750 return TC_PTR_FROM_CHUNK(tc);
1751 }
1752 while (tc && tc->prev) tc = tc->prev;
1753 if (tc) {
1754 tc = tc->parent;
1755 }
1756 }
1757 return NULL;
1758}
1759
1760/*
1761 show the parentage of a context
1762*/
1763void talloc_show_parents(const void *context, FILE *file)
1764{
1765 struct talloc_chunk *tc;
1766
1767 if (context == NULL) {
1768 fprintf(file, "talloc no parents for NULL\n");
1769 return;
1770 }
1771
1772 tc = talloc_chunk_from_ptr(context);
1773 fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
1774 while (tc) {
1775 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
1776 while (tc && tc->prev) tc = tc->prev;
1777 if (tc) {
1778 tc = tc->parent;
1779 }
1780 }
1781 fflush(file);
1782}
1783
1784/*
1785 return 1 if ptr is a parent of context
1786*/
1787int talloc_is_parent(const void *context, const void *ptr)
1788{
1789 struct talloc_chunk *tc;
1790
1791 if (context == NULL) {
1792 return 0;
1793 }
1794
1795 tc = talloc_chunk_from_ptr(context);
1796 while (tc) {
1797 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
1798 while (tc && tc->prev) tc = tc->prev;
1799 if (tc) {
1800 tc = tc->parent;
1801 }
1802 }
1803 return 0;
1804}