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