r17264: - remove unused includes from talloc
[kamenim/samba.git] / source4 / lib / talloc / talloc.c
1 /* 
2    Samba Unix SMB/CIFS implementation.
3
4    Samba trivial allocation library - new interface
5
6    NOTE: Please read talloc_guide.txt for full documentation
7
8    Copyright (C) Andrew Tridgell 2004
9    
10      ** NOTE! The following LGPL license applies to the talloc
11      ** library. This does NOT imply that all of Samba is released
12      ** under the LGPL
13    
14    This library is free software; you can redistribute it and/or
15    modify it under the terms of the GNU Lesser General Public
16    License as published by the Free Software Foundation; either
17    version 2 of the License, or (at your option) any later version.
18
19    This library is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22    Lesser General Public License for more details.
23
24    You should have received a copy of the GNU Lesser General Public
25    License along with this library; if not, write to the Free Software
26    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27 */
28
29 /*
30   inspired by http://swapped.cc/halloc/
31 */
32
33 #include "config.h"
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <errno.h>
39
40 #if defined(HAVE_STDARG_H)
41 #include <stdarg.h>
42 #elif defined (HAVE_VARARGS_H)
43 #include <varargs.h>
44 #else
45 #error "no var arg header"
46 #endif
47
48 #include "talloc.h"
49
50 /* use this to force every realloc to change the pointer, to stress test
51    code that might not cope */
52 #define ALWAYS_REALLOC 0
53
54
55 #define MAX_TALLOC_SIZE 0x10000000
56 #define TALLOC_MAGIC 0xe814ec70
57 #define TALLOC_FLAG_FREE 0x01
58 #define TALLOC_FLAG_LOOP 0x02
59 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
60
61 /* by default we abort when given a bad pointer (such as when talloc_free() is called 
62    on a pointer that came from malloc() */
63 #ifndef TALLOC_ABORT
64 #define TALLOC_ABORT(reason) abort()
65 #endif
66
67 #ifndef discard_const_p
68 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
69 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
70 #else
71 # define discard_const_p(type, ptr) ((type *)(ptr))
72 #endif
73 #endif
74
75 /* this null_context is only used if talloc_enable_leak_report() or
76    talloc_enable_leak_report_full() is called, otherwise it remains
77    NULL
78 */
79 static const void *null_context;
80 static void *cleanup_context;
81
82
83 struct talloc_reference_handle {
84         struct talloc_reference_handle *next, *prev;
85         void *ptr;
86 };
87
88 typedef int (*talloc_destructor_t)(void *);
89
90 struct talloc_chunk {
91         struct talloc_chunk *next, *prev;
92         struct talloc_chunk *parent, *child;
93         struct talloc_reference_handle *refs;
94         talloc_destructor_t destructor;
95         const char *name;
96         size_t size;
97         unsigned flags;
98 };
99
100 /* 16 byte alignment seems to keep everyone happy */
101 #define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
102 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
103
104 /* panic if we get a bad magic value */
105 static struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
106 {
107         const char *pp = ptr;
108         struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
109         if ((tc->flags & ~0xF) != TALLOC_MAGIC) { 
110                 TALLOC_ABORT("Bad talloc magic value - unknown value"); 
111         }
112         if (tc->flags & TALLOC_FLAG_FREE) {
113                 TALLOC_ABORT("Bad talloc magic value - double free"); 
114         }
115         return tc;
116 }
117
118 /* hook into the front of the list */
119 #define _TLIST_ADD(list, p) \
120 do { \
121         if (!(list)) { \
122                 (list) = (p); \
123                 (p)->next = (p)->prev = NULL; \
124         } else { \
125                 (list)->prev = (p); \
126                 (p)->next = (list); \
127                 (p)->prev = NULL; \
128                 (list) = (p); \
129         }\
130 } while (0)
131
132 /* remove an element from a list - element doesn't have to be in list. */
133 #define _TLIST_REMOVE(list, p) \
134 do { \
135         if ((p) == (list)) { \
136                 (list) = (p)->next; \
137                 if (list) (list)->prev = NULL; \
138         } else { \
139                 if ((p)->prev) (p)->prev->next = (p)->next; \
140                 if ((p)->next) (p)->next->prev = (p)->prev; \
141         } \
142         if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
143 } while (0)
144
145
146 /*
147   return the parent chunk of a pointer
148 */
149 static struct talloc_chunk *talloc_parent_chunk(const void *ptr)
150 {
151         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
152         while (tc->prev) tc=tc->prev;
153         return tc->parent;
154 }
155
156 void *talloc_parent(const void *ptr)
157 {
158         struct talloc_chunk *tc = talloc_parent_chunk(ptr);
159         return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
160 }
161
162 /* 
163    Allocate a bit of memory as a child of an existing pointer
164 */
165 void *_talloc(const void *context, size_t size)
166 {
167         struct talloc_chunk *tc;
168
169         if (context == NULL) {
170                 context = null_context;
171         }
172
173         if (size >= MAX_TALLOC_SIZE) {
174                 return NULL;
175         }
176
177         tc = malloc(TC_HDR_SIZE+size);
178         if (tc == NULL) return NULL;
179
180         tc->size = size;
181         tc->flags = TALLOC_MAGIC;
182         tc->destructor = NULL;
183         tc->child = NULL;
184         tc->name = NULL;
185         tc->refs = NULL;
186
187         if (context) {
188                 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
189
190                 tc->parent = parent;
191
192                 if (parent->child) {
193                         parent->child->parent = NULL;
194                 }
195
196                 _TLIST_ADD(parent->child, tc);
197         } else {
198                 tc->next = tc->prev = tc->parent = NULL;
199         }
200
201         return TC_PTR_FROM_CHUNK(tc);
202 }
203
204
205 /*
206   setup a destructor to be called on free of a pointer
207   the destructor should return 0 on success, or -1 on failure.
208   if the destructor fails then the free is failed, and the memory can
209   be continued to be used
210 */
211 void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
212 {
213         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
214         tc->destructor = destructor;
215 }
216
217 /*
218   increase the reference count on a piece of memory. 
219 */
220 void talloc_increase_ref_count(const void *ptr)
221 {
222         talloc_reference(null_context, ptr);
223 }
224
225 /*
226   helper for talloc_reference()
227 */
228 static int talloc_reference_destructor(struct talloc_reference_handle *handle)
229 {
230         struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
231         _TLIST_REMOVE(ptr_tc->refs, handle);
232         return 0;
233 }
234
235 /*
236   make a secondary reference to a pointer, hanging off the given context.
237   the pointer remains valid until both the original caller and this given
238   context are freed.
239   
240   the major use for this is when two different structures need to reference the 
241   same underlying data, and you want to be able to free the two instances separately,
242   and in either order
243 */
244 void *talloc_reference(const void *context, const void *ptr)
245 {
246         struct talloc_chunk *tc;
247         struct talloc_reference_handle *handle;
248         if (ptr == NULL) return NULL;
249
250         tc = talloc_chunk_from_ptr(ptr);
251         handle = talloc_named_const(context, sizeof(*handle), TALLOC_MAGIC_REFERENCE);
252
253         if (handle == NULL) return NULL;
254
255         /* note that we hang the destructor off the handle, not the
256            main context as that allows the caller to still setup their
257            own destructor on the context if they want to */
258         talloc_set_destructor(handle, talloc_reference_destructor);
259         handle->ptr = discard_const_p(void, ptr);
260         _TLIST_ADD(tc->refs, handle);
261         return handle->ptr;
262 }
263
264 /*
265   remove a secondary reference to a pointer. This undo's what
266   talloc_reference() has done. The context and pointer arguments
267   must match those given to a talloc_reference()
268 */
269 static int talloc_unreference(const void *context, const void *ptr)
270 {
271         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
272         struct talloc_reference_handle *h;
273
274         if (context == NULL) {
275                 context = null_context;
276         }
277
278         for (h=tc->refs;h;h=h->next) {
279                 struct talloc_chunk *p = talloc_parent_chunk(h);
280                 if (p == NULL) {
281                         if (context == NULL) break;
282                 } else if (TC_PTR_FROM_CHUNK(p) == context) {
283                         break;
284                 }
285         }
286         if (h == NULL) {
287                 return -1;
288         }
289
290         return talloc_free(h);
291 }
292
293 /*
294   remove a specific parent context from a pointer. This is a more
295   controlled varient of talloc_free()
296 */
297 int talloc_unlink(const void *context, void *ptr)
298 {
299         struct talloc_chunk *tc_p, *new_p;
300         void *new_parent;
301
302         if (ptr == NULL) {
303                 return -1;
304         }
305
306         if (context == NULL) {
307                 context = null_context;
308         }
309
310         if (talloc_unreference(context, ptr) == 0) {
311                 return 0;
312         }
313
314         if (context == NULL) {
315                 if (talloc_parent_chunk(ptr) != NULL) {
316                         return -1;
317                 }
318         } else {
319                 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
320                         return -1;
321                 }
322         }
323         
324         tc_p = talloc_chunk_from_ptr(ptr);
325
326         if (tc_p->refs == NULL) {
327                 return talloc_free(ptr);
328         }
329
330         new_p = talloc_parent_chunk(tc_p->refs);
331         if (new_p) {
332                 new_parent = TC_PTR_FROM_CHUNK(new_p);
333         } else {
334                 new_parent = NULL;
335         }
336
337         if (talloc_unreference(new_parent, ptr) != 0) {
338                 return -1;
339         }
340
341         talloc_steal(new_parent, ptr);
342
343         return 0;
344 }
345
346 /*
347   add a name to an existing pointer - va_list version
348 */
349 static const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
350
351 static const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
352 {
353         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
354         tc->name = talloc_vasprintf(ptr, fmt, ap);
355         if (tc->name) {
356                 talloc_set_name_const(tc->name, ".name");
357         }
358         return tc->name;
359 }
360
361 /*
362   add a name to an existing pointer
363 */
364 const char *talloc_set_name(const void *ptr, const char *fmt, ...)
365 {
366         const char *name;
367         va_list ap;
368         va_start(ap, fmt);
369         name = talloc_set_name_v(ptr, fmt, ap);
370         va_end(ap);
371         return name;
372 }
373
374 /*
375    more efficient way to add a name to a pointer - the name must point to a 
376    true string constant
377 */
378 void talloc_set_name_const(const void *ptr, const char *name)
379 {
380         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
381         tc->name = name;
382 }
383
384 /*
385   create a named talloc pointer. Any talloc pointer can be named, and
386   talloc_named() operates just like talloc() except that it allows you
387   to name the pointer.
388 */
389 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
390 {
391         va_list ap;
392         void *ptr;
393         const char *name;
394
395         ptr = _talloc(context, size);
396         if (ptr == NULL) return NULL;
397
398         va_start(ap, fmt);
399         name = talloc_set_name_v(ptr, fmt, ap);
400         va_end(ap);
401
402         if (name == NULL) {
403                 talloc_free(ptr);
404                 return NULL;
405         }
406
407         return ptr;
408 }
409
410 /*
411   create a named talloc pointer. Any talloc pointer can be named, and
412   talloc_named() operates just like talloc() except that it allows you
413   to name the pointer.
414 */
415 void *talloc_named_const(const void *context, size_t size, const char *name)
416 {
417         void *ptr;
418
419         ptr = _talloc(context, size);
420         if (ptr == NULL) {
421                 return NULL;
422         }
423
424         talloc_set_name_const(ptr, name);
425
426         return ptr;
427 }
428
429 /*
430   return the name of a talloc ptr, or "UNNAMED"
431 */
432 const char *talloc_get_name(const void *ptr)
433 {
434         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
435         if (tc->name == TALLOC_MAGIC_REFERENCE) {
436                 return ".reference";
437         }
438         if (tc->name) {
439                 return tc->name;
440         }
441         return "UNNAMED";
442 }
443
444
445 /*
446   check if a pointer has the given name. If it does, return the pointer,
447   otherwise return NULL
448 */
449 void *talloc_check_name(const void *ptr, const char *name)
450 {
451         const char *pname;
452         if (ptr == NULL) return NULL;
453         pname = talloc_get_name(ptr);
454         if (pname == name || strcmp(pname, name) == 0) {
455                 return discard_const_p(void, ptr);
456         }
457         return NULL;
458 }
459
460
461 /*
462   this is for compatibility with older versions of talloc
463 */
464 void *talloc_init(const char *fmt, ...)
465 {
466         va_list ap;
467         void *ptr;
468         const char *name;
469
470         ptr = _talloc(NULL, 0);
471         if (ptr == NULL) return NULL;
472
473         va_start(ap, fmt);
474         name = talloc_set_name_v(ptr, fmt, ap);
475         va_end(ap);
476
477         if (name == NULL) {
478                 talloc_free(ptr);
479                 return NULL;
480         }
481
482         return ptr;
483 }
484
485 /*
486   this is a replacement for the Samba3 talloc_destroy_pool functionality. It
487   should probably not be used in new code. It's in here to keep the talloc
488   code consistent across Samba 3 and 4.
489 */
490 void talloc_free_children(void *ptr)
491 {
492         struct talloc_chunk *tc;
493
494         if (ptr == NULL) {
495                 return;
496         }
497
498         tc = talloc_chunk_from_ptr(ptr);
499
500         while (tc->child) {
501                 /* we need to work out who will own an abandoned child
502                    if it cannot be freed. In priority order, the first
503                    choice is owner of any remaining reference to this
504                    pointer, the second choice is our parent, and the
505                    final choice is the null context. */
506                 void *child = TC_PTR_FROM_CHUNK(tc->child);
507                 const void *new_parent = null_context;
508                 if (tc->child->refs) {
509                         struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
510                         if (p) new_parent = TC_PTR_FROM_CHUNK(p);
511                 }
512                 if (talloc_free(child) == -1) {
513                         if (new_parent == null_context) {
514                                 struct talloc_chunk *p = talloc_parent_chunk(ptr);
515                                 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
516                         }
517                         talloc_steal(new_parent, child);
518                 }
519         }
520 }
521
522 /* 
523    free a talloc pointer. This also frees all child pointers of this 
524    pointer recursively
525
526    return 0 if the memory is actually freed, otherwise -1. The memory
527    will not be freed if the ref_count is > 1 or the destructor (if
528    any) returns non-zero
529 */
530 int talloc_free(void *ptr)
531 {
532         struct talloc_chunk *tc;
533         int old_errno;
534
535         if (ptr == NULL) {
536                 return -1;
537         }
538
539         tc = talloc_chunk_from_ptr(ptr);
540
541         if (tc->refs) {
542                 int is_child;
543                 /* check this is a reference from a child or grantchild
544                  * back to it's parent or grantparent
545                  *
546                  * in that case we need to remove the reference and
547                  * call another instance of talloc_free() on the current
548                  * pointer.
549                  */
550                 is_child = talloc_is_parent(tc->refs, ptr);
551                 talloc_free(tc->refs);
552                 if (is_child) {
553                         return talloc_free(ptr);
554                 }
555                 return -1;
556         }
557
558         if (tc->flags & TALLOC_FLAG_LOOP) {
559                 /* we have a free loop - stop looping */
560                 return 0;
561         }
562
563         if (tc->destructor) {
564                 talloc_destructor_t d = tc->destructor;
565                 if (d == (talloc_destructor_t)-1) {
566                         return -1;
567                 }
568                 tc->destructor = (talloc_destructor_t)-1;
569                 if (d(ptr) == -1) {
570                         tc->destructor = d;
571                         return -1;
572                 }
573                 tc->destructor = NULL;
574         }
575
576         if (tc->parent) {
577                 _TLIST_REMOVE(tc->parent->child, tc);
578                 if (tc->parent->child) {
579                         tc->parent->child->parent = tc->parent;
580                 }
581         } else {
582                 if (tc->prev) tc->prev->next = tc->next;
583                 if (tc->next) tc->next->prev = tc->prev;
584         }
585
586         tc->flags |= TALLOC_FLAG_LOOP;
587         talloc_free_children(ptr);
588
589         tc->flags |= TALLOC_FLAG_FREE;
590         old_errno = errno;
591         free(tc);
592         errno = old_errno;
593         return 0;
594 }
595
596
597
598 /*
599   A talloc version of realloc. The context argument is only used if
600   ptr is NULL
601 */
602 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
603 {
604         struct talloc_chunk *tc;
605         void *new_ptr;
606
607         /* size zero is equivalent to free() */
608         if (size == 0) {
609                 talloc_free(ptr);
610                 return NULL;
611         }
612
613         if (size >= MAX_TALLOC_SIZE) {
614                 return NULL;
615         }
616
617         /* realloc(NULL) is equavalent to malloc() */
618         if (ptr == NULL) {
619                 return talloc_named_const(context, size, name);
620         }
621
622         tc = talloc_chunk_from_ptr(ptr);
623
624         /* don't allow realloc on referenced pointers */
625         if (tc->refs) {
626                 return NULL;
627         }
628
629         /* by resetting magic we catch users of the old memory */
630         tc->flags |= TALLOC_FLAG_FREE;
631
632 #if ALWAYS_REALLOC
633         new_ptr = malloc(size + TC_HDR_SIZE);
634         if (new_ptr) {
635                 memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
636                 free(tc);
637         }
638 #else
639         new_ptr = realloc(tc, size + TC_HDR_SIZE);
640 #endif
641         if (!new_ptr) { 
642                 tc->flags &= ~TALLOC_FLAG_FREE; 
643                 return NULL; 
644         }
645
646         tc = new_ptr;
647         tc->flags &= ~TALLOC_FLAG_FREE; 
648         if (tc->parent) {
649                 tc->parent->child = new_ptr;
650         }
651         if (tc->child) {
652                 tc->child->parent = new_ptr;
653         }
654
655         if (tc->prev) {
656                 tc->prev->next = tc;
657         }
658         if (tc->next) {
659                 tc->next->prev = tc;
660         }
661
662         tc->size = size;
663         talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
664
665         return TC_PTR_FROM_CHUNK(tc);
666 }
667
668 /* 
669    move a lump of memory from one talloc context to another return the
670    ptr on success, or NULL if it could not be transferred.
671    passing NULL as ptr will always return NULL with no side effects.
672 */
673 void *_talloc_steal(const void *new_ctx, const void *ptr)
674 {
675         struct talloc_chunk *tc, *new_tc;
676
677         if (!ptr) {
678                 return NULL;
679         }
680
681         if (new_ctx == NULL) {
682                 new_ctx = null_context;
683         }
684
685         tc = talloc_chunk_from_ptr(ptr);
686
687         if (new_ctx == NULL) {
688                 if (tc->parent) {
689                         _TLIST_REMOVE(tc->parent->child, tc);
690                         if (tc->parent->child) {
691                                 tc->parent->child->parent = tc->parent;
692                         }
693                 } else {
694                         if (tc->prev) tc->prev->next = tc->next;
695                         if (tc->next) tc->next->prev = tc->prev;
696                 }
697                 
698                 tc->parent = tc->next = tc->prev = NULL;
699                 return discard_const_p(void, ptr);
700         }
701
702         new_tc = talloc_chunk_from_ptr(new_ctx);
703
704         if (tc == new_tc || tc->parent == new_tc) {
705                 return discard_const_p(void, ptr);
706         }
707
708         if (tc->parent) {
709                 _TLIST_REMOVE(tc->parent->child, tc);
710                 if (tc->parent->child) {
711                         tc->parent->child->parent = tc->parent;
712                 }
713         } else {
714                 if (tc->prev) tc->prev->next = tc->next;
715                 if (tc->next) tc->next->prev = tc->prev;
716         }
717
718         tc->parent = new_tc;
719         if (new_tc->child) new_tc->child->parent = NULL;
720         _TLIST_ADD(new_tc->child, tc);
721
722         return discard_const_p(void, ptr);
723 }
724
725 /*
726   return the total size of a talloc pool (subtree)
727 */
728 size_t talloc_total_size(const void *ptr)
729 {
730         size_t total = 0;
731         struct talloc_chunk *c, *tc;
732
733         if (ptr == NULL) {
734                 ptr = null_context;
735         }
736         if (ptr == NULL) {
737                 return 0;
738         }
739
740         tc = talloc_chunk_from_ptr(ptr);
741
742         if (tc->flags & TALLOC_FLAG_LOOP) {
743                 return 0;
744         }
745
746         tc->flags |= TALLOC_FLAG_LOOP;
747
748         total = tc->size;
749         for (c=tc->child;c;c=c->next) {
750                 total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
751         }
752
753         tc->flags &= ~TALLOC_FLAG_LOOP;
754
755         return total;
756 }
757
758 /*
759   return the total number of blocks in a talloc pool (subtree)
760 */
761 size_t talloc_total_blocks(const void *ptr)
762 {
763         size_t total = 0;
764         struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
765
766         if (tc->flags & TALLOC_FLAG_LOOP) {
767                 return 0;
768         }
769
770         tc->flags |= TALLOC_FLAG_LOOP;
771
772         total++;
773         for (c=tc->child;c;c=c->next) {
774                 total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
775         }
776
777         tc->flags &= ~TALLOC_FLAG_LOOP;
778
779         return total;
780 }
781
782 /*
783   return the number of external references to a pointer
784 */
785 static int talloc_reference_count(const void *ptr)
786 {
787         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
788         struct talloc_reference_handle *h;
789         int ret = 0;
790
791         for (h=tc->refs;h;h=h->next) {
792                 ret++;
793         }
794         return ret;
795 }
796
797 /*
798   report on memory usage by all children of a pointer, giving a full tree view
799 */
800 void talloc_report_depth(const void *ptr, FILE *f, int depth)
801 {
802         struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
803
804         if (tc->flags & TALLOC_FLAG_LOOP) {
805                 return;
806         }
807
808         tc->flags |= TALLOC_FLAG_LOOP;
809
810         for (c=tc->child;c;c=c->next) {
811                 if (c->name == TALLOC_MAGIC_REFERENCE) {
812                         struct talloc_reference_handle *handle = TC_PTR_FROM_CHUNK(c);
813                         const char *name2 = talloc_get_name(handle->ptr);
814                         fprintf(f, "%*sreference to: %s\n", depth*4, "", name2);
815                 } else {
816                         const char *name = talloc_get_name(TC_PTR_FROM_CHUNK(c));
817                         fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n", 
818                                 depth*4, "",
819                                 name,
820                                 (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)),
821                                 (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)),
822                                 talloc_reference_count(TC_PTR_FROM_CHUNK(c)));
823                         talloc_report_depth(TC_PTR_FROM_CHUNK(c), f, depth+1);
824                 }
825         }
826         tc->flags &= ~TALLOC_FLAG_LOOP;
827 }
828
829 /*
830   report on memory usage by all children of a pointer, giving a full tree view
831 */
832 void talloc_report_full(const void *ptr, FILE *f)
833 {
834         if (ptr == NULL) {
835                 ptr = null_context;
836         }
837         if (ptr == NULL) return;
838
839         fprintf(f,"full talloc report on '%s' (total %lu bytes in %lu blocks)\n", 
840                 talloc_get_name(ptr), 
841                 (unsigned long)talloc_total_size(ptr),
842                 (unsigned long)talloc_total_blocks(ptr));
843
844         talloc_report_depth(ptr, f, 1);
845         fflush(f);
846 }
847
848 /*
849   report on memory usage by all children of a pointer
850 */
851 void talloc_report(const void *ptr, FILE *f)
852 {
853         struct talloc_chunk *c, *tc;
854
855         if (ptr == NULL) {
856                 ptr = null_context;
857         }
858         if (ptr == NULL) return;
859        
860         fprintf(f,"talloc report on '%s' (total %lu bytes in %lu blocks)\n", 
861                 talloc_get_name(ptr), 
862                 (unsigned long)talloc_total_size(ptr),
863                 (unsigned long)talloc_total_blocks(ptr));
864
865         tc = talloc_chunk_from_ptr(ptr);
866
867         for (c=tc->child;c;c=c->next) {
868                 fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n", 
869                         talloc_get_name(TC_PTR_FROM_CHUNK(c)),
870                         (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)),
871                         (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)));
872         }
873         fflush(f);
874 }
875
876 /*
877   report on any memory hanging off the null context
878 */
879 static void talloc_report_null(void)
880 {
881         if (talloc_total_size(null_context) != 0) {
882                 talloc_report(null_context, stderr);
883         }
884 }
885
886 /*
887   report on any memory hanging off the null context
888 */
889 static void talloc_report_null_full(void)
890 {
891         if (talloc_total_size(null_context) != 0) {
892                 talloc_report_full(null_context, stderr);
893         }
894 }
895
896 /*
897   enable tracking of the NULL context
898 */
899 void talloc_enable_null_tracking(void)
900 {
901         if (null_context == NULL) {
902                 null_context = talloc_named_const(NULL, 0, "null_context");
903         }
904 }
905
906 /*
907   enable leak reporting on exit
908 */
909 void talloc_enable_leak_report(void)
910 {
911         talloc_enable_null_tracking();
912         atexit(talloc_report_null);
913 }
914
915 /*
916   enable full leak reporting on exit
917 */
918 void talloc_enable_leak_report_full(void)
919 {
920         talloc_enable_null_tracking();
921         atexit(talloc_report_null_full);
922 }
923
924 /* 
925    talloc and zero memory. 
926 */
927 void *_talloc_zero(const void *ctx, size_t size, const char *name)
928 {
929         void *p = talloc_named_const(ctx, size, name);
930
931         if (p) {
932                 memset(p, '\0', size);
933         }
934
935         return p;
936 }
937
938
939 /*
940   memdup with a talloc. 
941 */
942 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
943 {
944         void *newp = talloc_named_const(t, size, name);
945
946         if (newp) {
947                 memcpy(newp, p, size);
948         }
949
950         return newp;
951 }
952
953 /*
954   strdup with a talloc 
955 */
956 char *talloc_strdup(const void *t, const char *p)
957 {
958         char *ret;
959         if (!p) {
960                 return NULL;
961         }
962         ret = talloc_memdup(t, p, strlen(p) + 1);
963         if (ret) {
964                 talloc_set_name_const(ret, ret);
965         }
966         return ret;
967 }
968
969 /*
970  append to a talloced string 
971 */
972 char *talloc_append_string(const void *t, char *orig, const char *append)
973 {
974         char *ret;
975         size_t olen = strlen(orig);
976         size_t alenz;
977
978         if (!append)
979                 return orig;
980
981         alenz = strlen(append) + 1;
982
983         ret = talloc_realloc(t, orig, char, olen + alenz);
984         if (!ret)
985                 return NULL;
986
987         /* append the string with the trailing \0 */
988         memcpy(&ret[olen], append, alenz);
989
990         return ret;
991 }
992
993 /*
994   strndup with a talloc 
995 */
996 char *talloc_strndup(const void *t, const char *p, size_t n)
997 {
998         size_t len;
999         char *ret;
1000
1001         for (len=0; len<n && p[len]; len++) ;
1002
1003         ret = _talloc(t, len + 1);
1004         if (!ret) { return NULL; }
1005         memcpy(ret, p, len);
1006         ret[len] = 0;
1007         talloc_set_name_const(ret, ret);
1008         return ret;
1009 }
1010
1011 #ifndef HAVE_VA_COPY
1012 #ifdef HAVE___VA_COPY
1013 #define va_copy(dest, src) __va_copy(dest, src)
1014 #else
1015 #define va_copy(dest, src) (dest) = (src)
1016 #endif
1017 #endif
1018
1019 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1020 {       
1021         int len;
1022         char *ret;
1023         va_list ap2;
1024         char c;
1025         
1026         va_copy(ap2, ap);
1027
1028         /* this call looks strange, but it makes it work on older solaris boxes */
1029         if ((len = vsnprintf(&c, 1, fmt, ap2)) < 0) {
1030                 return NULL;
1031         }
1032
1033         ret = _talloc(t, len+1);
1034         if (ret) {
1035                 va_copy(ap2, ap);
1036                 vsnprintf(ret, len+1, fmt, ap2);
1037                 talloc_set_name_const(ret, ret);
1038         }
1039
1040         return ret;
1041 }
1042
1043
1044 /*
1045   Perform string formatting, and return a pointer to newly allocated
1046   memory holding the result, inside a memory pool.
1047  */
1048 char *talloc_asprintf(const void *t, const char *fmt, ...)
1049 {
1050         va_list ap;
1051         char *ret;
1052
1053         va_start(ap, fmt);
1054         ret = talloc_vasprintf(t, fmt, ap);
1055         va_end(ap);
1056         return ret;
1057 }
1058
1059
1060 /**
1061  * Realloc @p s to append the formatted result of @p fmt and @p ap,
1062  * and return @p s, which may have moved.  Good for gradually
1063  * accumulating output into a string buffer.
1064  **/
1065 char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1066 {       
1067         struct talloc_chunk *tc;
1068         int len, s_len;
1069         va_list ap2;
1070         char c;
1071
1072         if (s == NULL) {
1073                 return talloc_vasprintf(NULL, fmt, ap);
1074         }
1075
1076         tc = talloc_chunk_from_ptr(s);
1077
1078         va_copy(ap2, ap);
1079
1080         s_len = tc->size - 1;
1081         if ((len = vsnprintf(&c, 1, fmt, ap2)) <= 0) {
1082                 /* Either the vsnprintf failed or the format resulted in
1083                  * no characters being formatted. In the former case, we
1084                  * ought to return NULL, in the latter we ought to return
1085                  * the original string. Most current callers of this 
1086                  * function expect it to never return NULL.
1087                  */
1088                 return s;
1089         }
1090
1091         s = talloc_realloc(NULL, s, char, s_len + len+1);
1092         if (!s) return NULL;
1093
1094         va_copy(ap2, ap);
1095
1096         vsnprintf(s+s_len, len+1, fmt, ap2);
1097         talloc_set_name_const(s, s);
1098
1099         return s;
1100 }
1101
1102 /*
1103   Realloc @p s to append the formatted result of @p fmt and return @p
1104   s, which may have moved.  Good for gradually accumulating output
1105   into a string buffer.
1106  */
1107 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1108 {
1109         va_list ap;
1110
1111         va_start(ap, fmt);
1112         s = talloc_vasprintf_append(s, fmt, ap);
1113         va_end(ap);
1114         return s;
1115 }
1116
1117 /*
1118   alloc an array, checking for integer overflow in the array size
1119 */
1120 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1121 {
1122         if (count >= MAX_TALLOC_SIZE/el_size) {
1123                 return NULL;
1124         }
1125         return talloc_named_const(ctx, el_size * count, name);
1126 }
1127
1128 /*
1129   alloc an zero array, checking for integer overflow in the array size
1130 */
1131 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1132 {
1133         if (count >= MAX_TALLOC_SIZE/el_size) {
1134                 return NULL;
1135         }
1136         return _talloc_zero(ctx, el_size * count, name);
1137 }
1138
1139
1140 /*
1141   realloc an array, checking for integer overflow in the array size
1142 */
1143 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1144 {
1145         if (count >= MAX_TALLOC_SIZE/el_size) {
1146                 return NULL;
1147         }
1148         return _talloc_realloc(ctx, ptr, el_size * count, name);
1149 }
1150
1151 /*
1152   a function version of talloc_realloc(), so it can be passed as a function pointer
1153   to libraries that want a realloc function (a realloc function encapsulates
1154   all the basic capabilities of an allocation library, which is why this is useful)
1155 */
1156 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1157 {
1158         return _talloc_realloc(context, ptr, size, NULL);
1159 }
1160
1161
1162 static void talloc_autofree(void)
1163 {
1164         talloc_free(cleanup_context);
1165         cleanup_context = NULL;
1166 }
1167
1168 /*
1169   return a context which will be auto-freed on exit
1170   this is useful for reducing the noise in leak reports
1171 */
1172 void *talloc_autofree_context(void)
1173 {
1174         if (cleanup_context == NULL) {
1175                 cleanup_context = talloc_named_const(NULL, 0, "autofree_context");
1176                 atexit(talloc_autofree);
1177         }
1178         return cleanup_context;
1179 }
1180
1181 size_t talloc_get_size(const void *context)
1182 {
1183         struct talloc_chunk *tc;
1184
1185         if (context == NULL)
1186                 return 0;
1187
1188         tc = talloc_chunk_from_ptr(context);
1189
1190         return tc->size;
1191 }
1192
1193 /*
1194   find a parent of this context that has the given name, if any
1195 */
1196 void *talloc_find_parent_byname(const void *context, const char *name)
1197 {
1198         struct talloc_chunk *tc;
1199
1200         if (context == NULL) {
1201                 return NULL;
1202         }
1203
1204         tc = talloc_chunk_from_ptr(context);
1205         while (tc) {
1206                 if (tc->name && strcmp(tc->name, name) == 0) {
1207                         return TC_PTR_FROM_CHUNK(tc);
1208                 }
1209                 while (tc && tc->prev) tc = tc->prev;
1210                 if (tc) {
1211                         tc = tc->parent;
1212                 }
1213         }
1214         return NULL;
1215 }
1216
1217 /*
1218   show the parentage of a context
1219 */
1220 void talloc_show_parents(const void *context, FILE *file)
1221 {
1222         struct talloc_chunk *tc;
1223
1224         if (context == NULL) {
1225                 fprintf(file, "talloc no parents for NULL\n");
1226                 return;
1227         }
1228
1229         tc = talloc_chunk_from_ptr(context);
1230         fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
1231         while (tc) {
1232                 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
1233                 while (tc && tc->prev) tc = tc->prev;
1234                 if (tc) {
1235                         tc = tc->parent;
1236                 }
1237         }
1238 }
1239
1240 /*
1241   return 1 if ptr is a parent of context
1242 */
1243 int talloc_is_parent(const void *context, const char *ptr)
1244 {
1245         struct talloc_chunk *tc;
1246
1247         if (context == NULL) {
1248                 return 0;
1249         }
1250
1251         tc = talloc_chunk_from_ptr(context);
1252         while (tc) {
1253                 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
1254                 while (tc && tc->prev) tc = tc->prev;
1255                 if (tc) {
1256                         tc = tc->parent;
1257                 }
1258         }
1259         return 0;
1260 }