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