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