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