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