talloc: add TC_INVALIDATE_SHRINK_CHUNK() marco
[samba.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 #include "replace.h"
34 #include "talloc.h"
35
36 #ifdef TALLOC_BUILD_VERSION_MAJOR
37 #if (TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR)
38 #error "TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR"
39 #endif
40 #endif
41
42 #ifdef TALLOC_BUILD_VERSION_MINOR
43 #if (TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR)
44 #error "TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR"
45 #endif
46 #endif
47
48 /* use this to force every realloc to change the pointer, to stress test
49    code that might not cope */
50 #define ALWAYS_REALLOC 0
51
52
53 #define MAX_TALLOC_SIZE 0x10000000
54 #define TALLOC_MAGIC_BASE 0xe814ec70
55 #define TALLOC_MAGIC ( \
56         TALLOC_MAGIC_BASE + \
57         (TALLOC_VERSION_MAJOR << 12) + \
58         (TALLOC_VERSION_MINOR << 4) \
59 )
60
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 /* used to enable fill of memory on free, which can be useful for
108  * catching use after free errors when valgrind is too slow
109  */
110 static struct {
111         bool initialised;
112         bool enabled;
113         uint8_t fill_value;
114 } talloc_fill;
115
116 #define TALLOC_FILL_ENV "TALLOC_FREE_FILL"
117
118 /*
119  * do not wipe the header, to allow the
120  * double-free logic to still work
121  */
122 #define TC_INVALIDATE_FULL_FILL_CHUNK(_tc) do { \
123         if (unlikely(talloc_fill.enabled)) { \
124                 size_t _flen = (_tc)->size; \
125                 char *_fptr = TC_PTR_FROM_CHUNK(_tc); \
126                 memset(_fptr, talloc_fill.fill_value, _flen); \
127         } \
128 } while (0)
129
130 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
131 /* Mark the whole chunk as not accessable */
132 #define TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc) do { \
133         size_t _flen = TC_HDR_SIZE + (_tc)->size; \
134         char *_fptr = (char *)(_tc); \
135         VALGRIND_MAKE_MEM_NOACCESS(_fptr, _flen); \
136 } while(0)
137 #else
138 #define TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc) do { } while (0)
139 #endif
140
141 #define TC_INVALIDATE_FULL_CHUNK(_tc) do { \
142         TC_INVALIDATE_FULL_FILL_CHUNK(_tc); \
143         TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc); \
144 } while (0)
145
146 #define TC_INVALIDATE_SHRINK_FILL_CHUNK(_tc, _new_size) do { \
147         if (unlikely(talloc_fill.enabled)) { \
148                 size_t _flen = (_tc)->size - (_new_size); \
149                 char *_fptr = TC_PTR_FROM_CHUNK(_tc); \
150                 _fptr += (_new_size); \
151                 memset(_fptr, talloc_fill.fill_value, _flen); \
152         } \
153 } while (0)
154
155 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
156 /* Mark the unused bytes not accessable */
157 #define TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { \
158         size_t _flen = (_tc)->size - (_new_size); \
159         char *_fptr = TC_PTR_FROM_CHUNK(_tc); \
160         _fptr += (_new_size); \
161         VALGRIND_MAKE_MEM_NOACCESS(_fptr, _flen); \
162 } while (0)
163 #else
164 #define TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { } while (0)
165 #endif
166
167 #define TC_INVALIDATE_SHRINK_CHUNK(_tc, _new_size) do { \
168         TC_INVALIDATE_SHRINK_FILL_CHUNK(_tc, _new_size); \
169         TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size); \
170 } while (0)
171
172 struct talloc_reference_handle {
173         struct talloc_reference_handle *next, *prev;
174         void *ptr;
175         const char *location;
176 };
177
178 typedef int (*talloc_destructor_t)(void *);
179
180 struct talloc_chunk {
181         struct talloc_chunk *next, *prev;
182         struct talloc_chunk *parent, *child;
183         struct talloc_reference_handle *refs;
184         talloc_destructor_t destructor;
185         const char *name;
186         size_t size;
187         unsigned flags;
188
189         /*
190          * "pool" has dual use:
191          *
192          * For the talloc pool itself (i.e. TALLOC_FLAG_POOL is set), "pool"
193          * marks the end of the currently allocated area.
194          *
195          * For members of the pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool"
196          * is a pointer to the struct talloc_chunk of the pool that it was
197          * allocated from. This way children can quickly find the pool to chew
198          * from.
199          */
200         void *pool;
201 };
202
203 /* 16 byte alignment seems to keep everyone happy */
204 #define TC_ALIGN16(s) (((s)+15)&~15)
205 #define TC_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_chunk))
206 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
207
208 _PUBLIC_ int talloc_version_major(void)
209 {
210         return TALLOC_VERSION_MAJOR;
211 }
212
213 _PUBLIC_ int talloc_version_minor(void)
214 {
215         return TALLOC_VERSION_MINOR;
216 }
217
218 static void (*talloc_log_fn)(const char *message);
219
220 _PUBLIC_ void talloc_set_log_fn(void (*log_fn)(const char *message))
221 {
222         talloc_log_fn = log_fn;
223 }
224
225 static void talloc_log(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
226 static void talloc_log(const char *fmt, ...)
227 {
228         va_list ap;
229         char *message;
230
231         if (!talloc_log_fn) {
232                 return;
233         }
234
235         va_start(ap, fmt);
236         message = talloc_vasprintf(NULL, fmt, ap);
237         va_end(ap);
238
239         talloc_log_fn(message);
240         talloc_free(message);
241 }
242
243 static void talloc_log_stderr(const char *message)
244 {
245         fprintf(stderr, "%s", message);
246 }
247
248 _PUBLIC_ void talloc_set_log_stderr(void)
249 {
250         talloc_set_log_fn(talloc_log_stderr);
251 }
252
253 static void (*talloc_abort_fn)(const char *reason);
254
255 _PUBLIC_ void talloc_set_abort_fn(void (*abort_fn)(const char *reason))
256 {
257         talloc_abort_fn = abort_fn;
258 }
259
260 static void talloc_abort(const char *reason)
261 {
262         talloc_log("%s\n", reason);
263
264         if (!talloc_abort_fn) {
265                 TALLOC_ABORT(reason);
266         }
267
268         talloc_abort_fn(reason);
269 }
270
271 static void talloc_abort_magic(unsigned magic)
272 {
273         unsigned striped = magic - TALLOC_MAGIC_BASE;
274         unsigned major = (striped & 0xFFFFF000) >> 12;
275         unsigned minor = (striped & 0x00000FF0) >> 4;
276         talloc_log("Bad talloc magic[0x%08X/%u/%u] expected[0x%08X/%u/%u]\n",
277                    magic, major, minor,
278                    TALLOC_MAGIC, TALLOC_VERSION_MAJOR, TALLOC_VERSION_MINOR);
279         talloc_abort("Bad talloc magic value - wrong talloc version used/mixed");
280 }
281
282 static void talloc_abort_access_after_free(void)
283 {
284         talloc_abort("Bad talloc magic value - access after free");
285 }
286
287 static void talloc_abort_unknown_value(void)
288 {
289         talloc_abort("Bad talloc magic value - unknown value");
290 }
291
292 /* panic if we get a bad magic value */
293 static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
294 {
295         const char *pp = (const char *)ptr;
296         struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
297         if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) { 
298                 if ((tc->flags & (~0xFFF)) == TALLOC_MAGIC_BASE) {
299                         talloc_abort_magic(tc->flags & (~0xF));
300                         return NULL;
301                 }
302
303                 if (tc->flags & TALLOC_FLAG_FREE) {
304                         talloc_log("talloc: access after free error - first free may be at %s\n", tc->name);
305                         talloc_abort_access_after_free();
306                         return NULL;
307                 } else {
308                         talloc_abort_unknown_value();
309                         return NULL;
310                 }
311         }
312         return tc;
313 }
314
315 /* hook into the front of the list */
316 #define _TLIST_ADD(list, p) \
317 do { \
318         if (!(list)) { \
319                 (list) = (p); \
320                 (p)->next = (p)->prev = NULL; \
321         } else { \
322                 (list)->prev = (p); \
323                 (p)->next = (list); \
324                 (p)->prev = NULL; \
325                 (list) = (p); \
326         }\
327 } while (0)
328
329 /* remove an element from a list - element doesn't have to be in list. */
330 #define _TLIST_REMOVE(list, p) \
331 do { \
332         if ((p) == (list)) { \
333                 (list) = (p)->next; \
334                 if (list) (list)->prev = NULL; \
335         } else { \
336                 if ((p)->prev) (p)->prev->next = (p)->next; \
337                 if ((p)->next) (p)->next->prev = (p)->prev; \
338         } \
339         if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
340 } while (0)
341
342
343 /*
344   return the parent chunk of a pointer
345 */
346 static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr)
347 {
348         struct talloc_chunk *tc;
349
350         if (unlikely(ptr == NULL)) {
351                 return NULL;
352         }
353
354         tc = talloc_chunk_from_ptr(ptr);
355         while (tc->prev) tc=tc->prev;
356
357         return tc->parent;
358 }
359
360 _PUBLIC_ void *talloc_parent(const void *ptr)
361 {
362         struct talloc_chunk *tc = talloc_parent_chunk(ptr);
363         return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
364 }
365
366 /*
367   find parents name
368 */
369 _PUBLIC_ const char *talloc_parent_name(const void *ptr)
370 {
371         struct talloc_chunk *tc = talloc_parent_chunk(ptr);
372         return tc? tc->name : NULL;
373 }
374
375 /*
376   A pool carries an in-pool object count count in the first 16 bytes.
377   bytes. This is done to support talloc_steal() to a parent outside of the
378   pool. The count includes the pool itself, so a talloc_free() on a pool will
379   only destroy the pool if the count has dropped to zero. A talloc_free() of a
380   pool member will reduce the count, and eventually also call free(3) on the
381   pool memory.
382
383   The object count is not put into "struct talloc_chunk" because it is only
384   relevant for talloc pools and the alignment to 16 bytes would increase the
385   memory footprint of each talloc chunk by those 16 bytes.
386 */
387
388 #define TALLOC_POOL_HDR_SIZE 16
389
390 #define TC_POOL_SPACE_LEFT(_pool_tc) \
391         PTR_DIFF(TC_HDR_SIZE + (_pool_tc)->size + (char *)(_pool_tc), \
392                  (_pool_tc)->pool)
393
394 #define TC_POOL_FIRST_CHUNK(_pool_tc) \
395         ((void *)(TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE + (char *)(_pool_tc)))
396
397 #define TC_POOLMEM_CHUNK_SIZE(_tc) \
398         TC_ALIGN16(TC_HDR_SIZE + (_tc)->size)
399
400 #define TC_POOLMEM_NEXT_CHUNK(_tc) \
401         ((void *)(TC_POOLMEM_CHUNK_SIZE(tc) + (char*)(_tc)))
402
403 static unsigned int *talloc_pool_objectcount(struct talloc_chunk *tc)
404 {
405         return (unsigned int *)((char *)tc + TC_HDR_SIZE);
406 }
407
408 /*
409   Allocate from a pool
410 */
411
412 static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
413                                               size_t size)
414 {
415         struct talloc_chunk *pool_ctx = NULL;
416         size_t space_left;
417         struct talloc_chunk *result;
418         size_t chunk_size;
419
420         if (parent == NULL) {
421                 return NULL;
422         }
423
424         if (parent->flags & TALLOC_FLAG_POOL) {
425                 pool_ctx = parent;
426         }
427         else if (parent->flags & TALLOC_FLAG_POOLMEM) {
428                 pool_ctx = (struct talloc_chunk *)parent->pool;
429         }
430
431         if (pool_ctx == NULL) {
432                 return NULL;
433         }
434
435         space_left = TC_POOL_SPACE_LEFT(pool_ctx);
436
437         /*
438          * Align size to 16 bytes
439          */
440         chunk_size = TC_ALIGN16(size);
441
442         if (space_left < chunk_size) {
443                 return NULL;
444         }
445
446         result = (struct talloc_chunk *)pool_ctx->pool;
447
448 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
449         VALGRIND_MAKE_MEM_UNDEFINED(result, size);
450 #endif
451
452         pool_ctx->pool = (void *)((char *)result + chunk_size);
453
454         result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM;
455         result->pool = pool_ctx;
456
457         *talloc_pool_objectcount(pool_ctx) += 1;
458
459         return result;
460 }
461
462 /* 
463    Allocate a bit of memory as a child of an existing pointer
464 */
465 static inline void *__talloc(const void *context, size_t size)
466 {
467         struct talloc_chunk *tc = NULL;
468
469         if (unlikely(context == NULL)) {
470                 context = null_context;
471         }
472
473         if (unlikely(size >= MAX_TALLOC_SIZE)) {
474                 return NULL;
475         }
476
477         if (context != NULL) {
478                 tc = talloc_alloc_pool(talloc_chunk_from_ptr(context),
479                                        TC_HDR_SIZE+size);
480         }
481
482         if (tc == NULL) {
483                 tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size);
484                 if (unlikely(tc == NULL)) return NULL;
485                 tc->flags = TALLOC_MAGIC;
486                 tc->pool  = NULL;
487         }
488
489         tc->size = size;
490         tc->destructor = NULL;
491         tc->child = NULL;
492         tc->name = NULL;
493         tc->refs = NULL;
494
495         if (likely(context)) {
496                 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
497
498                 if (parent->child) {
499                         parent->child->parent = NULL;
500                         tc->next = parent->child;
501                         tc->next->prev = tc;
502                 } else {
503                         tc->next = NULL;
504                 }
505                 tc->parent = parent;
506                 tc->prev = NULL;
507                 parent->child = tc;
508         } else {
509                 tc->next = tc->prev = tc->parent = NULL;
510         }
511
512         return TC_PTR_FROM_CHUNK(tc);
513 }
514
515 /*
516  * Create a talloc pool
517  */
518
519 _PUBLIC_ void *talloc_pool(const void *context, size_t size)
520 {
521         void *result = __talloc(context, size + TALLOC_POOL_HDR_SIZE);
522         struct talloc_chunk *tc;
523
524         if (unlikely(result == NULL)) {
525                 return NULL;
526         }
527
528         tc = talloc_chunk_from_ptr(result);
529
530         tc->flags |= TALLOC_FLAG_POOL;
531         tc->pool = TC_POOL_FIRST_CHUNK(tc);
532
533         *talloc_pool_objectcount(tc) = 1;
534
535 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
536         VALGRIND_MAKE_MEM_NOACCESS(tc->pool, size);
537 #endif
538
539         return result;
540 }
541
542 /*
543   setup a destructor to be called on free of a pointer
544   the destructor should return 0 on success, or -1 on failure.
545   if the destructor fails then the free is failed, and the memory can
546   be continued to be used
547 */
548 _PUBLIC_ void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
549 {
550         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
551         tc->destructor = destructor;
552 }
553
554 /*
555   increase the reference count on a piece of memory. 
556 */
557 _PUBLIC_ int talloc_increase_ref_count(const void *ptr)
558 {
559         if (unlikely(!talloc_reference(null_context, ptr))) {
560                 return -1;
561         }
562         return 0;
563 }
564
565 /*
566   helper for talloc_reference()
567
568   this is referenced by a function pointer and should not be inline
569 */
570 static int talloc_reference_destructor(struct talloc_reference_handle *handle)
571 {
572         struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
573         _TLIST_REMOVE(ptr_tc->refs, handle);
574         return 0;
575 }
576
577 /*
578    more efficient way to add a name to a pointer - the name must point to a 
579    true string constant
580 */
581 static inline void _talloc_set_name_const(const void *ptr, const char *name)
582 {
583         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
584         tc->name = name;
585 }
586
587 /*
588   internal talloc_named_const()
589 */
590 static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
591 {
592         void *ptr;
593
594         ptr = __talloc(context, size);
595         if (unlikely(ptr == NULL)) {
596                 return NULL;
597         }
598
599         _talloc_set_name_const(ptr, name);
600
601         return ptr;
602 }
603
604 /*
605   make a secondary reference to a pointer, hanging off the given context.
606   the pointer remains valid until both the original caller and this given
607   context are freed.
608   
609   the major use for this is when two different structures need to reference the 
610   same underlying data, and you want to be able to free the two instances separately,
611   and in either order
612 */
613 _PUBLIC_ void *_talloc_reference_loc(const void *context, const void *ptr, const char *location)
614 {
615         struct talloc_chunk *tc;
616         struct talloc_reference_handle *handle;
617         if (unlikely(ptr == NULL)) return NULL;
618
619         tc = talloc_chunk_from_ptr(ptr);
620         handle = (struct talloc_reference_handle *)_talloc_named_const(context,
621                                                    sizeof(struct talloc_reference_handle),
622                                                    TALLOC_MAGIC_REFERENCE);
623         if (unlikely(handle == NULL)) return NULL;
624
625         /* note that we hang the destructor off the handle, not the
626            main context as that allows the caller to still setup their
627            own destructor on the context if they want to */
628         talloc_set_destructor(handle, talloc_reference_destructor);
629         handle->ptr = discard_const_p(void, ptr);
630         handle->location = location;
631         _TLIST_ADD(tc->refs, handle);
632         return handle->ptr;
633 }
634
635 static void *_talloc_steal_internal(const void *new_ctx, const void *ptr);
636
637 /* 
638    internal talloc_free call
639 */
640 static inline int _talloc_free_internal(void *ptr, const char *location)
641 {
642         struct talloc_chunk *tc;
643
644         if (unlikely(ptr == NULL)) {
645                 return -1;
646         }
647
648         /* possibly initialised the talloc fill value */
649         if (unlikely(!talloc_fill.initialised)) {
650                 const char *fill = getenv(TALLOC_FILL_ENV);
651                 if (fill != NULL) {
652                         talloc_fill.enabled = true;
653                         talloc_fill.fill_value = strtoul(fill, NULL, 0);
654                 }
655                 talloc_fill.initialised = true;
656         }
657
658         tc = talloc_chunk_from_ptr(ptr);
659
660         if (unlikely(tc->refs)) {
661                 int is_child;
662                 /* check if this is a reference from a child or
663                  * grandchild back to it's parent or grandparent
664                  *
665                  * in that case we need to remove the reference and
666                  * call another instance of talloc_free() on the current
667                  * pointer.
668                  */
669                 is_child = talloc_is_parent(tc->refs, ptr);
670                 _talloc_free_internal(tc->refs, location);
671                 if (is_child) {
672                         return _talloc_free_internal(ptr, location);
673                 }
674                 return -1;
675         }
676
677         if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
678                 /* we have a free loop - stop looping */
679                 return 0;
680         }
681
682         if (unlikely(tc->destructor)) {
683                 talloc_destructor_t d = tc->destructor;
684                 if (d == (talloc_destructor_t)-1) {
685                         return -1;
686                 }
687                 tc->destructor = (talloc_destructor_t)-1;
688                 if (d(ptr) == -1) {
689                         tc->destructor = d;
690                         return -1;
691                 }
692                 tc->destructor = NULL;
693         }
694
695         if (tc->parent) {
696                 _TLIST_REMOVE(tc->parent->child, tc);
697                 if (tc->parent->child) {
698                         tc->parent->child->parent = tc->parent;
699                 }
700         } else {
701                 if (tc->prev) tc->prev->next = tc->next;
702                 if (tc->next) tc->next->prev = tc->prev;
703         }
704
705         tc->flags |= TALLOC_FLAG_LOOP;
706
707         while (tc->child) {
708                 /* we need to work out who will own an abandoned child
709                    if it cannot be freed. In priority order, the first
710                    choice is owner of any remaining reference to this
711                    pointer, the second choice is our parent, and the
712                    final choice is the null context. */
713                 void *child = TC_PTR_FROM_CHUNK(tc->child);
714                 const void *new_parent = null_context;
715                 struct talloc_chunk *old_parent = NULL;
716                 if (unlikely(tc->child->refs)) {
717                         struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
718                         if (p) new_parent = TC_PTR_FROM_CHUNK(p);
719                 }
720                 /* finding the parent here is potentially quite
721                    expensive, but the alternative, which is to change
722                    talloc to always have a valid tc->parent pointer,
723                    makes realloc more expensive where there are a
724                    large number of children.
725
726                    The reason we need the parent pointer here is that
727                    if _talloc_free_internal() fails due to references
728                    or a failing destructor we need to re-parent, but
729                    the free call can invalidate the prev pointer.
730                 */
731                 if (new_parent == null_context && (tc->child->refs || tc->child->destructor)) {
732                         old_parent = talloc_parent_chunk(ptr);
733                 }
734                 if (unlikely(_talloc_free_internal(child, location) == -1)) {
735                         if (new_parent == null_context) {
736                                 struct talloc_chunk *p = old_parent;
737                                 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
738                         }
739                         _talloc_steal_internal(new_parent, child);
740                 }
741         }
742
743         tc->flags |= TALLOC_FLAG_FREE;
744
745         /* we mark the freed memory with where we called the free
746          * from. This means on a double free error we can report where
747          * the first free came from 
748          */      
749         tc->name = location;
750
751         if (tc->flags & (TALLOC_FLAG_POOL|TALLOC_FLAG_POOLMEM)) {
752                 struct talloc_chunk *pool;
753                 void *next_tc = NULL;
754                 unsigned int *pool_object_count;
755
756                 if (unlikely(tc->flags & TALLOC_FLAG_POOL)) {
757                         pool = tc;
758                 } else {
759                         pool = (struct talloc_chunk *)tc->pool;
760                         next_tc = TC_POOLMEM_NEXT_CHUNK(tc);
761
762                         TC_INVALIDATE_FULL_CHUNK(tc);
763                 }
764
765                 pool_object_count = talloc_pool_objectcount(pool);
766
767                 if (unlikely(*pool_object_count == 0)) {
768                         talloc_abort("Pool object count zero!");
769                         return 0;
770                 }
771
772                 *pool_object_count -= 1;
773
774                 if (unlikely(*pool_object_count == 1)) {
775                         /*
776                          * if there is just object left in the pool
777                          * it means this is the pool itself and
778                          * the rest is available for new objects
779                          * again.
780                          */
781                         pool->pool = TC_POOL_FIRST_CHUNK(pool);
782                 } else if (unlikely(*pool_object_count == 0)) {
783                         TC_INVALIDATE_FULL_CHUNK(pool);
784                         free(pool);
785                 } else if (pool->pool == next_tc) {
786                         /*
787                          * if pool->pool still points to end of
788                          * 'tc' (which is stored in the 'next_tc' variable),
789                          * we can reclaim the memory of 'tc'.
790                          */
791                         pool->pool = tc;
792                 }
793         } else {
794                 TC_INVALIDATE_FULL_CHUNK(tc);
795                 free(tc);
796         }
797         return 0;
798 }
799
800 /* 
801    move a lump of memory from one talloc context to another return the
802    ptr on success, or NULL if it could not be transferred.
803    passing NULL as ptr will always return NULL with no side effects.
804 */
805 static void *_talloc_steal_internal(const void *new_ctx, const void *ptr)
806 {
807         struct talloc_chunk *tc, *new_tc;
808
809         if (unlikely(!ptr)) {
810                 return NULL;
811         }
812
813         if (unlikely(new_ctx == NULL)) {
814                 new_ctx = null_context;
815         }
816
817         tc = talloc_chunk_from_ptr(ptr);
818
819         if (unlikely(new_ctx == NULL)) {
820                 if (tc->parent) {
821                         _TLIST_REMOVE(tc->parent->child, tc);
822                         if (tc->parent->child) {
823                                 tc->parent->child->parent = tc->parent;
824                         }
825                 } else {
826                         if (tc->prev) tc->prev->next = tc->next;
827                         if (tc->next) tc->next->prev = tc->prev;
828                 }
829                 
830                 tc->parent = tc->next = tc->prev = NULL;
831                 return discard_const_p(void, ptr);
832         }
833
834         new_tc = talloc_chunk_from_ptr(new_ctx);
835
836         if (unlikely(tc == new_tc || tc->parent == new_tc)) {
837                 return discard_const_p(void, ptr);
838         }
839
840         if (tc->parent) {
841                 _TLIST_REMOVE(tc->parent->child, tc);
842                 if (tc->parent->child) {
843                         tc->parent->child->parent = tc->parent;
844                 }
845         } else {
846                 if (tc->prev) tc->prev->next = tc->next;
847                 if (tc->next) tc->next->prev = tc->prev;
848         }
849
850         tc->parent = new_tc;
851         if (new_tc->child) new_tc->child->parent = NULL;
852         _TLIST_ADD(new_tc->child, tc);
853
854         return discard_const_p(void, ptr);
855 }
856
857 /* 
858    move a lump of memory from one talloc context to another return the
859    ptr on success, or NULL if it could not be transferred.
860    passing NULL as ptr will always return NULL with no side effects.
861 */
862 _PUBLIC_ void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const char *location)
863 {
864         struct talloc_chunk *tc;
865
866         if (unlikely(ptr == NULL)) {
867                 return NULL;
868         }
869         
870         tc = talloc_chunk_from_ptr(ptr);
871         
872         if (unlikely(tc->refs != NULL) && talloc_parent(ptr) != new_ctx) {
873                 struct talloc_reference_handle *h;
874
875                 talloc_log("WARNING: talloc_steal with references at %s\n",
876                            location);
877
878                 for (h=tc->refs; h; h=h->next) {
879                         talloc_log("\treference at %s\n",
880                                    h->location);
881                 }
882         }
883
884 #if 0
885         /* this test is probably too expensive to have on in the
886            normal build, but it useful for debugging */
887         if (talloc_is_parent(new_ctx, ptr)) {
888                 talloc_log("WARNING: stealing into talloc child at %s\n", location);
889         }
890 #endif
891         
892         return _talloc_steal_internal(new_ctx, ptr);
893 }
894
895 /* 
896    this is like a talloc_steal(), but you must supply the old
897    parent. This resolves the ambiguity in a talloc_steal() which is
898    called on a context that has more than one parent (via references)
899
900    The old parent can be either a reference or a parent
901 */
902 _PUBLIC_ void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr)
903 {
904         struct talloc_chunk *tc;
905         struct talloc_reference_handle *h;
906
907         if (unlikely(ptr == NULL)) {
908                 return NULL;
909         }
910
911         if (old_parent == talloc_parent(ptr)) {
912                 return _talloc_steal_internal(new_parent, ptr);
913         }
914
915         tc = talloc_chunk_from_ptr(ptr);
916         for (h=tc->refs;h;h=h->next) {
917                 if (talloc_parent(h) == old_parent) {
918                         if (_talloc_steal_internal(new_parent, h) != h) {
919                                 return NULL;
920                         }
921                         return discard_const_p(void, ptr);
922                 }
923         }       
924
925         /* it wasn't a parent */
926         return NULL;
927 }
928
929 /*
930   remove a secondary reference to a pointer. This undo's what
931   talloc_reference() has done. The context and pointer arguments
932   must match those given to a talloc_reference()
933 */
934 static inline int talloc_unreference(const void *context, const void *ptr)
935 {
936         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
937         struct talloc_reference_handle *h;
938
939         if (unlikely(context == NULL)) {
940                 context = null_context;
941         }
942
943         for (h=tc->refs;h;h=h->next) {
944                 struct talloc_chunk *p = talloc_parent_chunk(h);
945                 if (p == NULL) {
946                         if (context == NULL) break;
947                 } else if (TC_PTR_FROM_CHUNK(p) == context) {
948                         break;
949                 }
950         }
951         if (h == NULL) {
952                 return -1;
953         }
954
955         return _talloc_free_internal(h, __location__);
956 }
957
958 /*
959   remove a specific parent context from a pointer. This is a more
960   controlled varient of talloc_free()
961 */
962 _PUBLIC_ int talloc_unlink(const void *context, void *ptr)
963 {
964         struct talloc_chunk *tc_p, *new_p;
965         void *new_parent;
966
967         if (ptr == NULL) {
968                 return -1;
969         }
970
971         if (context == NULL) {
972                 context = null_context;
973         }
974
975         if (talloc_unreference(context, ptr) == 0) {
976                 return 0;
977         }
978
979         if (context == NULL) {
980                 if (talloc_parent_chunk(ptr) != NULL) {
981                         return -1;
982                 }
983         } else {
984                 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
985                         return -1;
986                 }
987         }
988         
989         tc_p = talloc_chunk_from_ptr(ptr);
990
991         if (tc_p->refs == NULL) {
992                 return _talloc_free_internal(ptr, __location__);
993         }
994
995         new_p = talloc_parent_chunk(tc_p->refs);
996         if (new_p) {
997                 new_parent = TC_PTR_FROM_CHUNK(new_p);
998         } else {
999                 new_parent = NULL;
1000         }
1001
1002         if (talloc_unreference(new_parent, ptr) != 0) {
1003                 return -1;
1004         }
1005
1006         _talloc_steal_internal(new_parent, ptr);
1007
1008         return 0;
1009 }
1010
1011 /*
1012   add a name to an existing pointer - va_list version
1013 */
1014 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
1015
1016 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
1017 {
1018         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1019         tc->name = talloc_vasprintf(ptr, fmt, ap);
1020         if (likely(tc->name)) {
1021                 _talloc_set_name_const(tc->name, ".name");
1022         }
1023         return tc->name;
1024 }
1025
1026 /*
1027   add a name to an existing pointer
1028 */
1029 _PUBLIC_ const char *talloc_set_name(const void *ptr, const char *fmt, ...)
1030 {
1031         const char *name;
1032         va_list ap;
1033         va_start(ap, fmt);
1034         name = talloc_set_name_v(ptr, fmt, ap);
1035         va_end(ap);
1036         return name;
1037 }
1038
1039
1040 /*
1041   create a named talloc pointer. Any talloc pointer can be named, and
1042   talloc_named() operates just like talloc() except that it allows you
1043   to name the pointer.
1044 */
1045 _PUBLIC_ void *talloc_named(const void *context, size_t size, const char *fmt, ...)
1046 {
1047         va_list ap;
1048         void *ptr;
1049         const char *name;
1050
1051         ptr = __talloc(context, size);
1052         if (unlikely(ptr == NULL)) return NULL;
1053
1054         va_start(ap, fmt);
1055         name = talloc_set_name_v(ptr, fmt, ap);
1056         va_end(ap);
1057
1058         if (unlikely(name == NULL)) {
1059                 _talloc_free_internal(ptr, __location__);
1060                 return NULL;
1061         }
1062
1063         return ptr;
1064 }
1065
1066 /*
1067   return the name of a talloc ptr, or "UNNAMED"
1068 */
1069 _PUBLIC_ const char *talloc_get_name(const void *ptr)
1070 {
1071         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1072         if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
1073                 return ".reference";
1074         }
1075         if (likely(tc->name)) {
1076                 return tc->name;
1077         }
1078         return "UNNAMED";
1079 }
1080
1081
1082 /*
1083   check if a pointer has the given name. If it does, return the pointer,
1084   otherwise return NULL
1085 */
1086 _PUBLIC_ void *talloc_check_name(const void *ptr, const char *name)
1087 {
1088         const char *pname;
1089         if (unlikely(ptr == NULL)) return NULL;
1090         pname = talloc_get_name(ptr);
1091         if (likely(pname == name || strcmp(pname, name) == 0)) {
1092                 return discard_const_p(void, ptr);
1093         }
1094         return NULL;
1095 }
1096
1097 static void talloc_abort_type_missmatch(const char *location,
1098                                         const char *name,
1099                                         const char *expected)
1100 {
1101         const char *reason;
1102
1103         reason = talloc_asprintf(NULL,
1104                                  "%s: Type mismatch: name[%s] expected[%s]",
1105                                  location,
1106                                  name?name:"NULL",
1107                                  expected);
1108         if (!reason) {
1109                 reason = "Type mismatch";
1110         }
1111
1112         talloc_abort(reason);
1113 }
1114
1115 _PUBLIC_ void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location)
1116 {
1117         const char *pname;
1118
1119         if (unlikely(ptr == NULL)) {
1120                 talloc_abort_type_missmatch(location, NULL, name);
1121                 return NULL;
1122         }
1123
1124         pname = talloc_get_name(ptr);
1125         if (likely(pname == name || strcmp(pname, name) == 0)) {
1126                 return discard_const_p(void, ptr);
1127         }
1128
1129         talloc_abort_type_missmatch(location, pname, name);
1130         return NULL;
1131 }
1132
1133 /*
1134   this is for compatibility with older versions of talloc
1135 */
1136 _PUBLIC_ void *talloc_init(const char *fmt, ...)
1137 {
1138         va_list ap;
1139         void *ptr;
1140         const char *name;
1141
1142         ptr = __talloc(NULL, 0);
1143         if (unlikely(ptr == NULL)) return NULL;
1144
1145         va_start(ap, fmt);
1146         name = talloc_set_name_v(ptr, fmt, ap);
1147         va_end(ap);
1148
1149         if (unlikely(name == NULL)) {
1150                 _talloc_free_internal(ptr, __location__);
1151                 return NULL;
1152         }
1153
1154         return ptr;
1155 }
1156
1157 /*
1158   this is a replacement for the Samba3 talloc_destroy_pool functionality. It
1159   should probably not be used in new code. It's in here to keep the talloc
1160   code consistent across Samba 3 and 4.
1161 */
1162 _PUBLIC_ void talloc_free_children(void *ptr)
1163 {
1164         struct talloc_chunk *tc;
1165
1166         if (unlikely(ptr == NULL)) {
1167                 return;
1168         }
1169
1170         tc = talloc_chunk_from_ptr(ptr);
1171
1172         while (tc->child) {
1173                 /* we need to work out who will own an abandoned child
1174                    if it cannot be freed. In priority order, the first
1175                    choice is owner of any remaining reference to this
1176                    pointer, the second choice is our parent, and the
1177                    final choice is the null context. */
1178                 void *child = TC_PTR_FROM_CHUNK(tc->child);
1179                 const void *new_parent = null_context;
1180                 if (unlikely(tc->child->refs)) {
1181                         struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
1182                         if (p) new_parent = TC_PTR_FROM_CHUNK(p);
1183                 }
1184                 if (unlikely(talloc_free(child) == -1)) {
1185                         if (new_parent == null_context) {
1186                                 struct talloc_chunk *p = talloc_parent_chunk(ptr);
1187                                 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
1188                         }
1189                         _talloc_steal_internal(new_parent, child);
1190                 }
1191         }
1192 }
1193
1194 /* 
1195    Allocate a bit of memory as a child of an existing pointer
1196 */
1197 _PUBLIC_ void *_talloc(const void *context, size_t size)
1198 {
1199         return __talloc(context, size);
1200 }
1201
1202 /*
1203   externally callable talloc_set_name_const()
1204 */
1205 _PUBLIC_ void talloc_set_name_const(const void *ptr, const char *name)
1206 {
1207         _talloc_set_name_const(ptr, name);
1208 }
1209
1210 /*
1211   create a named talloc pointer. Any talloc pointer can be named, and
1212   talloc_named() operates just like talloc() except that it allows you
1213   to name the pointer.
1214 */
1215 _PUBLIC_ void *talloc_named_const(const void *context, size_t size, const char *name)
1216 {
1217         return _talloc_named_const(context, size, name);
1218 }
1219
1220 /* 
1221    free a talloc pointer. This also frees all child pointers of this 
1222    pointer recursively
1223
1224    return 0 if the memory is actually freed, otherwise -1. The memory
1225    will not be freed if the ref_count is > 1 or the destructor (if
1226    any) returns non-zero
1227 */
1228 _PUBLIC_ int _talloc_free(void *ptr, const char *location)
1229 {
1230         struct talloc_chunk *tc;
1231
1232         if (unlikely(ptr == NULL)) {
1233                 return -1;
1234         }
1235         
1236         tc = talloc_chunk_from_ptr(ptr);
1237         
1238         if (unlikely(tc->refs != NULL)) {
1239                 struct talloc_reference_handle *h;
1240
1241                 if (talloc_parent(ptr) == null_context && tc->refs->next == NULL) {
1242                         /* in this case we do know which parent should
1243                            get this pointer, as there is really only
1244                            one parent */
1245                         return talloc_unlink(null_context, ptr);
1246                 }
1247
1248                 talloc_log("ERROR: talloc_free with references at %s\n",
1249                            location);
1250
1251                 for (h=tc->refs; h; h=h->next) {
1252                         talloc_log("\treference at %s\n",
1253                                    h->location);
1254                 }
1255                 return -1;
1256         }
1257         
1258         return _talloc_free_internal(ptr, location);
1259 }
1260
1261
1262
1263 /*
1264   A talloc version of realloc. The context argument is only used if
1265   ptr is NULL
1266 */
1267 _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
1268 {
1269         struct talloc_chunk *tc;
1270         void *new_ptr;
1271         bool malloced = false;
1272         struct talloc_chunk *pool_tc = NULL;
1273
1274         /* size zero is equivalent to free() */
1275         if (unlikely(size == 0)) {
1276                 talloc_unlink(context, ptr);
1277                 return NULL;
1278         }
1279
1280         if (unlikely(size >= MAX_TALLOC_SIZE)) {
1281                 return NULL;
1282         }
1283
1284         /* realloc(NULL) is equivalent to malloc() */
1285         if (ptr == NULL) {
1286                 return _talloc_named_const(context, size, name);
1287         }
1288
1289         tc = talloc_chunk_from_ptr(ptr);
1290
1291         /* don't allow realloc on referenced pointers */
1292         if (unlikely(tc->refs)) {
1293                 return NULL;
1294         }
1295
1296         /* don't let anybody try to realloc a talloc_pool */
1297         if (unlikely(tc->flags & TALLOC_FLAG_POOL)) {
1298                 return NULL;
1299         }
1300
1301         /* don't let anybody try to realloc a talloc_pool */
1302         if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) {
1303                 pool_tc = (struct talloc_chunk *)tc->pool;
1304         }
1305
1306 #if (ALWAYS_REALLOC == 0)
1307         /* don't shrink if we have less than 1k to gain */
1308         if (size < tc->size) {
1309                 if (pool_tc) {
1310                         void *next_tc = TC_POOLMEM_NEXT_CHUNK(tc);
1311                         TC_INVALIDATE_SHRINK_CHUNK(tc, size);
1312                         tc->size = size;
1313                         if (next_tc == pool_tc->pool) {
1314                                 pool_tc->pool = TC_POOLMEM_NEXT_CHUNK(tc);
1315                         }
1316                         return ptr;
1317                 } else if ((tc->size - size) < 1024) {
1318                         TC_INVALIDATE_SHRINK_CHUNK(tc, size);
1319                         /* do not shrink if we have less than 1k to gain */
1320                         tc->size = size;
1321                         return ptr;
1322                 }
1323         } else if (tc->size == size) {
1324                 /*
1325                  * do not change the pointer if it is exactly
1326                  * the same size.
1327                  */
1328                 return ptr;
1329         }
1330 #endif
1331
1332         /* by resetting magic we catch users of the old memory */
1333         tc->flags |= TALLOC_FLAG_FREE;
1334
1335 #if ALWAYS_REALLOC
1336         if (pool_tc) {
1337                 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE);
1338                 *talloc_pool_objectcount(pool_tc) -= 1;
1339
1340                 if (new_ptr == NULL) {
1341                         new_ptr = malloc(TC_HDR_SIZE+size);
1342                         malloced = true;
1343                 }
1344
1345                 if (new_ptr) {
1346                         memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
1347                         TC_INVALIDATE_FULL_CHUNK(tc);
1348                 }
1349         } else {
1350                 new_ptr = malloc(size + TC_HDR_SIZE);
1351                 if (new_ptr) {
1352                         memcpy(new_ptr, tc, MIN(tc->size, size) + TC_HDR_SIZE);
1353                         free(tc);
1354                 }
1355         }
1356 #else
1357         if (pool_tc) {
1358                 void *next_tc = TC_POOLMEM_NEXT_CHUNK(tc);
1359                 size_t old_chunk_size = TC_POOLMEM_CHUNK_SIZE(tc);
1360                 size_t new_chunk_size = TC_ALIGN16(TC_HDR_SIZE + size);
1361                 size_t space_needed;
1362                 size_t space_left;
1363
1364                 if (*talloc_pool_objectcount(pool_tc) == 2) {
1365                         /*
1366                          * optimize for the case where 'tc' is the only
1367                          * chunk in the pool.
1368                          */
1369                         space_needed = new_chunk_size;
1370                         space_left = pool_tc->size - TALLOC_POOL_HDR_SIZE;
1371
1372                         if (space_left >= space_needed) {
1373                                 size_t old_used = TC_HDR_SIZE + tc->size;
1374                                 pool_tc->pool = TC_POOL_FIRST_CHUNK(pool_tc);
1375 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
1376                                 /*
1377                                  * we need to prepare the memmove into
1378                                  * the unaccessable area.
1379                                  */
1380                                 {
1381                                         size_t diff = PTR_DIFF(tc, pool_tc->pool);
1382                                         size_t flen = MIN(diff, old_used);
1383                                         char *fptr = (char *)pool_tc->pool;
1384                                         VALGRIND_MAKE_MEM_UNDEFINED(fptr, flen);
1385                                 }
1386 #endif
1387                                 memmove(pool_tc->pool, tc, old_used);
1388                                 new_ptr = pool_tc->pool;
1389
1390                                 pool_tc->pool = new_chunk_size + (char *)new_ptr;
1391                                 goto got_new_ptr;
1392                         }
1393
1394                         next_tc = NULL;
1395                 }
1396
1397                 if (new_chunk_size == old_chunk_size) {
1398                         tc->flags &= ~TALLOC_FLAG_FREE;
1399                         tc->size = size;
1400                         return ptr;
1401                 }
1402
1403                 if (next_tc == pool_tc->pool) {
1404                         /*
1405                          * optimize for the case where 'tc' is the last
1406                          * chunk in the pool.
1407                          */
1408                         space_needed = new_chunk_size - old_chunk_size;
1409                         space_left = TC_POOL_SPACE_LEFT(pool_tc);
1410
1411                         if (space_left >= space_needed) {
1412                                 tc->flags &= ~TALLOC_FLAG_FREE;
1413                                 tc->size = size;
1414                                 pool_tc->pool = TC_POOLMEM_NEXT_CHUNK(tc);
1415                                 return ptr;
1416                         }
1417                 }
1418
1419                 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE);
1420                 *talloc_pool_objectcount(pool_tc) -= 1;
1421
1422                 if (new_ptr == NULL) {
1423                         new_ptr = malloc(TC_HDR_SIZE+size);
1424                         malloced = true;
1425                 }
1426
1427                 if (new_ptr) {
1428                         memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
1429                         TC_INVALIDATE_FULL_CHUNK(tc);
1430
1431                         if (*talloc_pool_objectcount(pool_tc) == 1) {
1432                                 /*
1433                                  * If the pool is empty now reclaim everything.
1434                                  */
1435                                 pool_tc->pool = TC_POOL_FIRST_CHUNK(pool_tc);
1436                         } else if (next_tc == pool_tc->pool) {
1437                                 /*
1438                                  * If it was reallocated and tc was the last
1439                                  * chunk, we can reclaim the memory of tc.
1440                                  */
1441                                 pool_tc->pool = tc;
1442                         }
1443                 }
1444         }
1445         else {
1446                 new_ptr = realloc(tc, size + TC_HDR_SIZE);
1447         }
1448 got_new_ptr:
1449 #endif
1450         if (unlikely(!new_ptr)) {       
1451                 tc->flags &= ~TALLOC_FLAG_FREE; 
1452                 return NULL; 
1453         }
1454
1455         tc = (struct talloc_chunk *)new_ptr;
1456         tc->flags &= ~TALLOC_FLAG_FREE;
1457         if (malloced) {
1458                 tc->flags &= ~TALLOC_FLAG_POOLMEM;
1459         }
1460         if (tc->parent) {
1461                 tc->parent->child = tc;
1462         }
1463         if (tc->child) {
1464                 tc->child->parent = tc;
1465         }
1466
1467         if (tc->prev) {
1468                 tc->prev->next = tc;
1469         }
1470         if (tc->next) {
1471                 tc->next->prev = tc;
1472         }
1473
1474         tc->size = size;
1475         _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
1476
1477         return TC_PTR_FROM_CHUNK(tc);
1478 }
1479
1480 /*
1481   a wrapper around talloc_steal() for situations where you are moving a pointer
1482   between two structures, and want the old pointer to be set to NULL
1483 */
1484 _PUBLIC_ void *_talloc_move(const void *new_ctx, const void *_pptr)
1485 {
1486         const void **pptr = discard_const_p(const void *,_pptr);
1487         void *ret = talloc_steal(new_ctx, discard_const_p(void, *pptr));
1488         (*pptr) = NULL;
1489         return ret;
1490 }
1491
1492 /*
1493   return the total size of a talloc pool (subtree)
1494 */
1495 _PUBLIC_ size_t talloc_total_size(const void *ptr)
1496 {
1497         size_t total = 0;
1498         struct talloc_chunk *c, *tc;
1499
1500         if (ptr == NULL) {
1501                 ptr = null_context;
1502         }
1503         if (ptr == NULL) {
1504                 return 0;
1505         }
1506
1507         tc = talloc_chunk_from_ptr(ptr);
1508
1509         if (tc->flags & TALLOC_FLAG_LOOP) {
1510                 return 0;
1511         }
1512
1513         tc->flags |= TALLOC_FLAG_LOOP;
1514
1515         if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) {
1516                 total = tc->size;
1517         }
1518         for (c=tc->child;c;c=c->next) {
1519                 total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
1520         }
1521
1522         tc->flags &= ~TALLOC_FLAG_LOOP;
1523
1524         return total;
1525 }
1526
1527 /*
1528   return the total number of blocks in a talloc pool (subtree)
1529 */
1530 _PUBLIC_ size_t talloc_total_blocks(const void *ptr)
1531 {
1532         size_t total = 0;
1533         struct talloc_chunk *c, *tc;
1534
1535         if (ptr == NULL) {
1536                 ptr = null_context;
1537         }
1538         if (ptr == NULL) {
1539                 return 0;
1540         }
1541
1542         tc = talloc_chunk_from_ptr(ptr);
1543
1544         if (tc->flags & TALLOC_FLAG_LOOP) {
1545                 return 0;
1546         }
1547
1548         tc->flags |= TALLOC_FLAG_LOOP;
1549
1550         total++;
1551         for (c=tc->child;c;c=c->next) {
1552                 total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
1553         }
1554
1555         tc->flags &= ~TALLOC_FLAG_LOOP;
1556
1557         return total;
1558 }
1559
1560 /*
1561   return the number of external references to a pointer
1562 */
1563 _PUBLIC_ size_t talloc_reference_count(const void *ptr)
1564 {
1565         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1566         struct talloc_reference_handle *h;
1567         size_t ret = 0;
1568
1569         for (h=tc->refs;h;h=h->next) {
1570                 ret++;
1571         }
1572         return ret;
1573 }
1574
1575 /*
1576   report on memory usage by all children of a pointer, giving a full tree view
1577 */
1578 _PUBLIC_ void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1579                             void (*callback)(const void *ptr,
1580                                              int depth, int max_depth,
1581                                              int is_ref,
1582                                              void *private_data),
1583                             void *private_data)
1584 {
1585         struct talloc_chunk *c, *tc;
1586
1587         if (ptr == NULL) {
1588                 ptr = null_context;
1589         }
1590         if (ptr == NULL) return;
1591
1592         tc = talloc_chunk_from_ptr(ptr);
1593
1594         if (tc->flags & TALLOC_FLAG_LOOP) {
1595                 return;
1596         }
1597
1598         callback(ptr, depth, max_depth, 0, private_data);
1599
1600         if (max_depth >= 0 && depth >= max_depth) {
1601                 return;
1602         }
1603
1604         tc->flags |= TALLOC_FLAG_LOOP;
1605         for (c=tc->child;c;c=c->next) {
1606                 if (c->name == TALLOC_MAGIC_REFERENCE) {
1607                         struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
1608                         callback(h->ptr, depth + 1, max_depth, 1, private_data);
1609                 } else {
1610                         talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
1611                 }
1612         }
1613         tc->flags &= ~TALLOC_FLAG_LOOP;
1614 }
1615
1616 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
1617 {
1618         const char *name = talloc_get_name(ptr);
1619         FILE *f = (FILE *)_f;
1620
1621         if (is_ref) {
1622                 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
1623                 return;
1624         }
1625
1626         if (depth == 0) {
1627                 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", 
1628                         (max_depth < 0 ? "full " :""), name,
1629                         (unsigned long)talloc_total_size(ptr),
1630                         (unsigned long)talloc_total_blocks(ptr));
1631                 return;
1632         }
1633
1634         fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n", 
1635                 depth*4, "",
1636                 name,
1637                 (unsigned long)talloc_total_size(ptr),
1638                 (unsigned long)talloc_total_blocks(ptr),
1639                 (int)talloc_reference_count(ptr), ptr);
1640
1641 #if 0
1642         fprintf(f, "content: ");
1643         if (talloc_total_size(ptr)) {
1644                 int tot = talloc_total_size(ptr);
1645                 int i;
1646
1647                 for (i = 0; i < tot; i++) {
1648                         if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
1649                                 fprintf(f, "%c", ((char *)ptr)[i]);
1650                         } else {
1651                                 fprintf(f, "~%02x", ((char *)ptr)[i]);
1652                         }
1653                 }
1654         }
1655         fprintf(f, "\n");
1656 #endif
1657 }
1658
1659 /*
1660   report on memory usage by all children of a pointer, giving a full tree view
1661 */
1662 _PUBLIC_ void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
1663 {
1664         if (f) {
1665                 talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
1666                 fflush(f);
1667         }
1668 }
1669
1670 /*
1671   report on memory usage by all children of a pointer, giving a full tree view
1672 */
1673 _PUBLIC_ void talloc_report_full(const void *ptr, FILE *f)
1674 {
1675         talloc_report_depth_file(ptr, 0, -1, f);
1676 }
1677
1678 /*
1679   report on memory usage by all children of a pointer
1680 */
1681 _PUBLIC_ void talloc_report(const void *ptr, FILE *f)
1682 {
1683         talloc_report_depth_file(ptr, 0, 1, f);
1684 }
1685
1686 /*
1687   report on any memory hanging off the null context
1688 */
1689 static void talloc_report_null(void)
1690 {
1691         if (talloc_total_size(null_context) != 0) {
1692                 talloc_report(null_context, stderr);
1693         }
1694 }
1695
1696 /*
1697   report on any memory hanging off the null context
1698 */
1699 static void talloc_report_null_full(void)
1700 {
1701         if (talloc_total_size(null_context) != 0) {
1702                 talloc_report_full(null_context, stderr);
1703         }
1704 }
1705
1706 /*
1707   enable tracking of the NULL context
1708 */
1709 _PUBLIC_ void talloc_enable_null_tracking(void)
1710 {
1711         if (null_context == NULL) {
1712                 null_context = _talloc_named_const(NULL, 0, "null_context");
1713                 if (autofree_context != NULL) {
1714                         talloc_reparent(NULL, null_context, autofree_context);
1715                 }
1716         }
1717 }
1718
1719 /*
1720   enable tracking of the NULL context, not moving the autofree context
1721   into the NULL context. This is needed for the talloc testsuite
1722 */
1723 _PUBLIC_ void talloc_enable_null_tracking_no_autofree(void)
1724 {
1725         if (null_context == NULL) {
1726                 null_context = _talloc_named_const(NULL, 0, "null_context");
1727         }
1728 }
1729
1730 /*
1731   disable tracking of the NULL context
1732 */
1733 _PUBLIC_ void talloc_disable_null_tracking(void)
1734 {
1735         if (null_context != NULL) {
1736                 /* we have to move any children onto the real NULL
1737                    context */
1738                 struct talloc_chunk *tc, *tc2;
1739                 tc = talloc_chunk_from_ptr(null_context);
1740                 for (tc2 = tc->child; tc2; tc2=tc2->next) {
1741                         if (tc2->parent == tc) tc2->parent = NULL;
1742                         if (tc2->prev == tc) tc2->prev = NULL;
1743                 }
1744                 for (tc2 = tc->next; tc2; tc2=tc2->next) {
1745                         if (tc2->parent == tc) tc2->parent = NULL;
1746                         if (tc2->prev == tc) tc2->prev = NULL;
1747                 }
1748                 tc->child = NULL;
1749                 tc->next = NULL;
1750         }
1751         talloc_free(null_context);
1752         null_context = NULL;
1753 }
1754
1755 /*
1756   enable leak reporting on exit
1757 */
1758 _PUBLIC_ void talloc_enable_leak_report(void)
1759 {
1760         talloc_enable_null_tracking();
1761         atexit(talloc_report_null);
1762 }
1763
1764 /*
1765   enable full leak reporting on exit
1766 */
1767 _PUBLIC_ void talloc_enable_leak_report_full(void)
1768 {
1769         talloc_enable_null_tracking();
1770         atexit(talloc_report_null_full);
1771 }
1772
1773 /* 
1774    talloc and zero memory. 
1775 */
1776 _PUBLIC_ void *_talloc_zero(const void *ctx, size_t size, const char *name)
1777 {
1778         void *p = _talloc_named_const(ctx, size, name);
1779
1780         if (p) {
1781                 memset(p, '\0', size);
1782         }
1783
1784         return p;
1785 }
1786
1787 /*
1788   memdup with a talloc. 
1789 */
1790 _PUBLIC_ void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
1791 {
1792         void *newp = _talloc_named_const(t, size, name);
1793
1794         if (likely(newp)) {
1795                 memcpy(newp, p, size);
1796         }
1797
1798         return newp;
1799 }
1800
1801 static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
1802 {
1803         char *ret;
1804
1805         ret = (char *)__talloc(t, len + 1);
1806         if (unlikely(!ret)) return NULL;
1807
1808         memcpy(ret, p, len);
1809         ret[len] = 0;
1810
1811         _talloc_set_name_const(ret, ret);
1812         return ret;
1813 }
1814
1815 /*
1816   strdup with a talloc
1817 */
1818 _PUBLIC_ char *talloc_strdup(const void *t, const char *p)
1819 {
1820         if (unlikely(!p)) return NULL;
1821         return __talloc_strlendup(t, p, strlen(p));
1822 }
1823
1824 /*
1825   strndup with a talloc
1826 */
1827 _PUBLIC_ char *talloc_strndup(const void *t, const char *p, size_t n)
1828 {
1829         if (unlikely(!p)) return NULL;
1830         return __talloc_strlendup(t, p, strnlen(p, n));
1831 }
1832
1833 static inline char *__talloc_strlendup_append(char *s, size_t slen,
1834                                               const char *a, size_t alen)
1835 {
1836         char *ret;
1837
1838         ret = talloc_realloc(NULL, s, char, slen + alen + 1);
1839         if (unlikely(!ret)) return NULL;
1840
1841         /* append the string and the trailing \0 */
1842         memcpy(&ret[slen], a, alen);
1843         ret[slen+alen] = 0;
1844
1845         _talloc_set_name_const(ret, ret);
1846         return ret;
1847 }
1848
1849 /*
1850  * Appends at the end of the string.
1851  */
1852 _PUBLIC_ char *talloc_strdup_append(char *s, const char *a)
1853 {
1854         if (unlikely(!s)) {
1855                 return talloc_strdup(NULL, a);
1856         }
1857
1858         if (unlikely(!a)) {
1859                 return s;
1860         }
1861
1862         return __talloc_strlendup_append(s, strlen(s), a, strlen(a));
1863 }
1864
1865 /*
1866  * Appends at the end of the talloc'ed buffer,
1867  * not the end of the string.
1868  */
1869 _PUBLIC_ char *talloc_strdup_append_buffer(char *s, const char *a)
1870 {
1871         size_t slen;
1872
1873         if (unlikely(!s)) {
1874                 return talloc_strdup(NULL, a);
1875         }
1876
1877         if (unlikely(!a)) {
1878                 return s;
1879         }
1880
1881         slen = talloc_get_size(s);
1882         if (likely(slen > 0)) {
1883                 slen--;
1884         }
1885
1886         return __talloc_strlendup_append(s, slen, a, strlen(a));
1887 }
1888
1889 /*
1890  * Appends at the end of the string.
1891  */
1892 _PUBLIC_ char *talloc_strndup_append(char *s, const char *a, size_t n)
1893 {
1894         if (unlikely(!s)) {
1895                 return talloc_strdup(NULL, a);
1896         }
1897
1898         if (unlikely(!a)) {
1899                 return s;
1900         }
1901
1902         return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n));
1903 }
1904
1905 /*
1906  * Appends at the end of the talloc'ed buffer,
1907  * not the end of the string.
1908  */
1909 _PUBLIC_ char *talloc_strndup_append_buffer(char *s, const char *a, size_t n)
1910 {
1911         size_t slen;
1912
1913         if (unlikely(!s)) {
1914                 return talloc_strdup(NULL, a);
1915         }
1916
1917         if (unlikely(!a)) {
1918                 return s;
1919         }
1920
1921         slen = talloc_get_size(s);
1922         if (likely(slen > 0)) {
1923                 slen--;
1924         }
1925
1926         return __talloc_strlendup_append(s, slen, a, strnlen(a, n));
1927 }
1928
1929 #ifndef HAVE_VA_COPY
1930 #ifdef HAVE___VA_COPY
1931 #define va_copy(dest, src) __va_copy(dest, src)
1932 #else
1933 #define va_copy(dest, src) (dest) = (src)
1934 #endif
1935 #endif
1936
1937 _PUBLIC_ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1938 {
1939         int len;
1940         char *ret;
1941         va_list ap2;
1942         char c;
1943
1944         /* this call looks strange, but it makes it work on older solaris boxes */
1945         va_copy(ap2, ap);
1946         len = vsnprintf(&c, 1, fmt, ap2);
1947         va_end(ap2);
1948         if (unlikely(len < 0)) {
1949                 return NULL;
1950         }
1951
1952         ret = (char *)__talloc(t, len+1);
1953         if (unlikely(!ret)) return NULL;
1954
1955         va_copy(ap2, ap);
1956         vsnprintf(ret, len+1, fmt, ap2);
1957         va_end(ap2);
1958
1959         _talloc_set_name_const(ret, ret);
1960         return ret;
1961 }
1962
1963
1964 /*
1965   Perform string formatting, and return a pointer to newly allocated
1966   memory holding the result, inside a memory pool.
1967  */
1968 _PUBLIC_ char *talloc_asprintf(const void *t, const char *fmt, ...)
1969 {
1970         va_list ap;
1971         char *ret;
1972
1973         va_start(ap, fmt);
1974         ret = talloc_vasprintf(t, fmt, ap);
1975         va_end(ap);
1976         return ret;
1977 }
1978
1979 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1980                                                  const char *fmt, va_list ap)
1981                                                  PRINTF_ATTRIBUTE(3,0);
1982
1983 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1984                                                  const char *fmt, va_list ap)
1985 {
1986         ssize_t alen;
1987         va_list ap2;
1988         char c;
1989
1990         va_copy(ap2, ap);
1991         alen = vsnprintf(&c, 1, fmt, ap2);
1992         va_end(ap2);
1993
1994         if (alen <= 0) {
1995                 /* Either the vsnprintf failed or the format resulted in
1996                  * no characters being formatted. In the former case, we
1997                  * ought to return NULL, in the latter we ought to return
1998                  * the original string. Most current callers of this
1999                  * function expect it to never return NULL.
2000                  */
2001                 return s;
2002         }
2003
2004         s = talloc_realloc(NULL, s, char, slen + alen + 1);
2005         if (!s) return NULL;
2006
2007         va_copy(ap2, ap);
2008         vsnprintf(s + slen, alen + 1, fmt, ap2);
2009         va_end(ap2);
2010
2011         _talloc_set_name_const(s, s);
2012         return s;
2013 }
2014
2015 /**
2016  * Realloc @p s to append the formatted result of @p fmt and @p ap,
2017  * and return @p s, which may have moved.  Good for gradually
2018  * accumulating output into a string buffer. Appends at the end
2019  * of the string.
2020  **/
2021 _PUBLIC_ char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
2022 {
2023         if (unlikely(!s)) {
2024                 return talloc_vasprintf(NULL, fmt, ap);
2025         }
2026
2027         return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap);
2028 }
2029
2030 /**
2031  * Realloc @p s to append the formatted result of @p fmt and @p ap,
2032  * and return @p s, which may have moved. Always appends at the
2033  * end of the talloc'ed buffer, not the end of the string.
2034  **/
2035 _PUBLIC_ char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap)
2036 {
2037         size_t slen;
2038
2039         if (unlikely(!s)) {
2040                 return talloc_vasprintf(NULL, fmt, ap);
2041         }
2042
2043         slen = talloc_get_size(s);
2044         if (likely(slen > 0)) {
2045                 slen--;
2046         }
2047
2048         return __talloc_vaslenprintf_append(s, slen, fmt, ap);
2049 }
2050
2051 /*
2052   Realloc @p s to append the formatted result of @p fmt and return @p
2053   s, which may have moved.  Good for gradually accumulating output
2054   into a string buffer.
2055  */
2056 _PUBLIC_ char *talloc_asprintf_append(char *s, const char *fmt, ...)
2057 {
2058         va_list ap;
2059
2060         va_start(ap, fmt);
2061         s = talloc_vasprintf_append(s, fmt, ap);
2062         va_end(ap);
2063         return s;
2064 }
2065
2066 /*
2067   Realloc @p s to append the formatted result of @p fmt and return @p
2068   s, which may have moved.  Good for gradually accumulating output
2069   into a buffer.
2070  */
2071 _PUBLIC_ char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...)
2072 {
2073         va_list ap;
2074
2075         va_start(ap, fmt);
2076         s = talloc_vasprintf_append_buffer(s, fmt, ap);
2077         va_end(ap);
2078         return s;
2079 }
2080
2081 /*
2082   alloc an array, checking for integer overflow in the array size
2083 */
2084 _PUBLIC_ void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
2085 {
2086         if (count >= MAX_TALLOC_SIZE/el_size) {
2087                 return NULL;
2088         }
2089         return _talloc_named_const(ctx, el_size * count, name);
2090 }
2091
2092 /*
2093   alloc an zero array, checking for integer overflow in the array size
2094 */
2095 _PUBLIC_ void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
2096 {
2097         if (count >= MAX_TALLOC_SIZE/el_size) {
2098                 return NULL;
2099         }
2100         return _talloc_zero(ctx, el_size * count, name);
2101 }
2102
2103 /*
2104   realloc an array, checking for integer overflow in the array size
2105 */
2106 _PUBLIC_ void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
2107 {
2108         if (count >= MAX_TALLOC_SIZE/el_size) {
2109                 return NULL;
2110         }
2111         return _talloc_realloc(ctx, ptr, el_size * count, name);
2112 }
2113
2114 /*
2115   a function version of talloc_realloc(), so it can be passed as a function pointer
2116   to libraries that want a realloc function (a realloc function encapsulates
2117   all the basic capabilities of an allocation library, which is why this is useful)
2118 */
2119 _PUBLIC_ void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
2120 {
2121         return _talloc_realloc(context, ptr, size, NULL);
2122 }
2123
2124
2125 static int talloc_autofree_destructor(void *ptr)
2126 {
2127         autofree_context = NULL;
2128         return 0;
2129 }
2130
2131 static void talloc_autofree(void)
2132 {
2133         talloc_free(autofree_context);
2134 }
2135
2136 /*
2137   return a context which will be auto-freed on exit
2138   this is useful for reducing the noise in leak reports
2139 */
2140 _PUBLIC_ void *talloc_autofree_context(void)
2141 {
2142         if (autofree_context == NULL) {
2143                 autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
2144                 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
2145                 atexit(talloc_autofree);
2146         }
2147         return autofree_context;
2148 }
2149
2150 _PUBLIC_ size_t talloc_get_size(const void *context)
2151 {
2152         struct talloc_chunk *tc;
2153
2154         if (context == NULL) {
2155                 context = null_context;
2156         }
2157         if (context == NULL) {
2158                 return 0;
2159         }
2160
2161         tc = talloc_chunk_from_ptr(context);
2162
2163         return tc->size;
2164 }
2165
2166 /*
2167   find a parent of this context that has the given name, if any
2168 */
2169 _PUBLIC_ void *talloc_find_parent_byname(const void *context, const char *name)
2170 {
2171         struct talloc_chunk *tc;
2172
2173         if (context == NULL) {
2174                 return NULL;
2175         }
2176
2177         tc = talloc_chunk_from_ptr(context);
2178         while (tc) {
2179                 if (tc->name && strcmp(tc->name, name) == 0) {
2180                         return TC_PTR_FROM_CHUNK(tc);
2181                 }
2182                 while (tc && tc->prev) tc = tc->prev;
2183                 if (tc) {
2184                         tc = tc->parent;
2185                 }
2186         }
2187         return NULL;
2188 }
2189
2190 /*
2191   show the parentage of a context
2192 */
2193 _PUBLIC_ void talloc_show_parents(const void *context, FILE *file)
2194 {
2195         struct talloc_chunk *tc;
2196
2197         if (context == NULL) {
2198                 fprintf(file, "talloc no parents for NULL\n");
2199                 return;
2200         }
2201
2202         tc = talloc_chunk_from_ptr(context);
2203         fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
2204         while (tc) {
2205                 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
2206                 while (tc && tc->prev) tc = tc->prev;
2207                 if (tc) {
2208                         tc = tc->parent;
2209                 }
2210         }
2211         fflush(file);
2212 }
2213
2214 /*
2215   return 1 if ptr is a parent of context
2216 */
2217 static int _talloc_is_parent(const void *context, const void *ptr, int depth)
2218 {
2219         struct talloc_chunk *tc;
2220
2221         if (context == NULL) {
2222                 return 0;
2223         }
2224
2225         tc = talloc_chunk_from_ptr(context);
2226         while (tc && depth > 0) {
2227                 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
2228                 while (tc && tc->prev) tc = tc->prev;
2229                 if (tc) {
2230                         tc = tc->parent;
2231                         depth--;
2232                 }
2233         }
2234         return 0;
2235 }
2236
2237 /*
2238   return 1 if ptr is a parent of context
2239 */
2240 _PUBLIC_ int talloc_is_parent(const void *context, const void *ptr)
2241 {
2242         return _talloc_is_parent(context, ptr, TALLOC_MAX_DEPTH);
2243 }