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