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