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