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