b81cf7221b155ef8ca0e077fad773a5824a383a1
[bbaumbach/samba-autobuild/.git] / source4 / lib / talloc.c
1 /* 
2    Samba Unix SMB/CIFS implementation.
3
4    Samba temporary memory allocation functions - new interface
5
6    Copyright (C) Andrew Tridgell 2004
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 /*
24   inspired by http://swapped.cc/halloc/
25 */
26
27 #include "includes.h"
28
29 #define MAX_TALLOC_SIZE 0x10000000
30 #define TALLOC_MAGIC 0xe814ec4f
31 #define TALLOC_MAGIC_FREE 0x7faebef3
32
33 static const void *null_context;
34
35 struct talloc_reference_handle {
36         struct talloc_reference_handle *next, *prev;
37         void *ptr;
38 };
39
40 typedef int (*talloc_destructor_t)(void *);
41
42 struct talloc_chunk {
43         struct talloc_chunk *next, *prev;
44         struct talloc_chunk *parent, *child;
45         struct talloc_reference_handle *refs;
46         size_t size;
47         uint_t magic;
48         talloc_destructor_t destructor;
49         const char *name;
50 };
51
52 /* panic if we get a bad magic value */
53 static struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
54 {
55         struct talloc_chunk *tc = ((struct talloc_chunk *)discard_const(ptr))-1;
56         if (tc->magic != TALLOC_MAGIC) {
57                 if (tc->magic == TALLOC_MAGIC_FREE) {
58                         smb_panic("Bad talloc magic value - double free\n");
59                 } else {
60                         smb_panic("Bad talloc magic value\n");
61                 }
62         }
63         return tc;
64 }
65
66
67 /*
68   return the parent chunk of a pointer
69 */
70 static struct talloc_chunk *talloc_parent_chunk(const void *ptr)
71 {
72         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
73         while (tc->prev) tc=tc->prev;
74         return tc->parent;
75 }
76
77 /* 
78    Allocate a bit of memory as a child of an existing pointer
79 */
80 void *_talloc(const void *context, size_t size)
81 {
82         struct talloc_chunk *tc;
83
84         if (context == NULL) {
85                 context = null_context;
86         }
87
88         if (size >= MAX_TALLOC_SIZE) {
89                 return NULL;
90         }
91
92         tc = malloc(sizeof(*tc)+size);
93         if (tc == NULL) {
94                 return NULL;
95         }
96
97         tc->size = size;
98         tc->magic = TALLOC_MAGIC;
99         tc->destructor = NULL;
100         tc->child = NULL;
101         tc->name = NULL;
102         tc->refs = NULL;
103
104         if (context) {
105                 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
106
107                 tc->parent = parent;
108
109                 if (parent->child) {
110                         parent->child->parent = NULL;
111                 }
112
113                 DLIST_ADD(parent->child, tc);
114         } else {
115                 tc->next = tc->prev = tc->parent = NULL;
116         }
117
118         return (void *)(tc+1);
119 }
120
121
122 /*
123   setup a destructor to be called on free of a pointer
124   the destructor should return 0 on success, or -1 on failure.
125   if the destructor fails then the free is failed, and the memory can
126   be continued to be used
127 */
128 void talloc_set_destructor(const void *ptr, int (*destructor)(void *))
129 {
130         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
131         tc->destructor = destructor;
132 }
133
134 /*
135   increase the reference count on a piece of memory. 
136 */
137 void talloc_increase_ref_count(const void *ptr)
138 {
139         talloc_reference(null_context, ptr);
140 }
141
142 /*
143   helper for talloc_reference()
144 */
145 static int talloc_reference_destructor(void *ptr)
146 {
147         struct talloc_reference_handle *handle = ptr;
148         struct talloc_chunk *tc1 = talloc_chunk_from_ptr(ptr);
149         struct talloc_chunk *tc2 = talloc_chunk_from_ptr(handle->ptr);
150         if (tc1->destructor != (talloc_destructor_t)-1) {
151                 tc1->destructor = NULL;
152         }
153         DLIST_REMOVE(tc2->refs, handle);
154         talloc_free(handle);
155         return 0;
156 }
157
158 /*
159   make a secondary reference to a pointer, hanging off the given context.
160   the pointer remains valid until both the original caller and this given
161   context are freed.
162   
163   the major use for this is when two different structures need to reference the 
164   same underlying data, and you want to be able to free the two instances separately,
165   and in either order
166 */
167 void *talloc_reference(const void *context, const void *ptr)
168 {
169         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
170         struct talloc_reference_handle *handle;
171         handle = talloc_named_const(context, sizeof(*handle), ".reference");
172         if (handle == NULL) {
173                 return NULL;
174         }
175         /* note that we hang the destructor off the handle, not the
176            main context as that allows the caller to still setup their
177            own destructor on the context if they want to */
178         talloc_set_destructor(handle, talloc_reference_destructor);
179         handle->ptr = discard_const(ptr);
180         DLIST_ADD(tc->refs, handle);
181         return handle->ptr;
182 }
183
184 /*
185   remove a secondary reference to a pointer. This undo's what
186   talloc_reference() has done. The context and pointer arguments
187   must match those given to a talloc_reference()
188 */
189 void *talloc_unreference(const void *context, const void *ptr)
190 {
191         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
192         struct talloc_reference_handle *h;
193
194         if (context == NULL) {
195                 context = null_context;
196         }
197
198         for (h=tc->refs;h;h=h->next) {
199                 struct talloc_chunk *p = talloc_parent_chunk(h);
200                 if ((p==NULL && context==NULL) || p+1 == context) break;
201         }
202         if (h == NULL) {
203                 return NULL;
204         }
205
206         talloc_set_destructor(h, NULL);
207         DLIST_REMOVE(tc->refs, h);
208         talloc_free(h);
209         return discard_const(ptr);
210 }
211
212 /*
213   add a name to an existing pointer - va_list version
214 */
215 static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
216
217 static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
218 {
219         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
220         tc->name = talloc_vasprintf(ptr, fmt, ap);
221         if (tc->name) {
222                 talloc_set_name_const(tc->name, ".name");
223         }
224 }
225
226 /*
227   add a name to an existing pointer
228 */
229 void talloc_set_name(const void *ptr, const char *fmt, ...) _PRINTF_ATTRIBUTE(2,3)
230 {
231         va_list ap;
232         va_start(ap, fmt);
233         talloc_set_name_v(ptr, fmt, ap);
234         va_end(ap);
235 }
236
237 /*
238    more efficient way to add a name to a pointer - the name must point to a 
239    true string constant
240 */
241 void talloc_set_name_const(const void *ptr, const char *name)
242 {
243         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
244         tc->name = name;
245 }
246
247 /*
248   create a named talloc pointer. Any talloc pointer can be named, and
249   talloc_named() operates just like talloc() except that it allows you
250   to name the pointer.
251 */
252 void *talloc_named(const void *context, size_t size, 
253                    const char *fmt, ...) _PRINTF_ATTRIBUTE(3,4)
254 {
255         va_list ap;
256         void *ptr;
257
258         ptr = _talloc(context, size);
259         if (ptr == NULL) {
260                 return NULL;
261         }
262
263         va_start(ap, fmt);
264         talloc_set_name_v(ptr, fmt, ap);
265         va_end(ap);
266
267         return ptr;
268 }
269
270 /*
271   create a named talloc pointer. Any talloc pointer can be named, and
272   talloc_named() operates just like talloc() except that it allows you
273   to name the pointer.
274 */
275 void *talloc_named_const(const void *context, size_t size, const char *name)
276 {
277         void *ptr;
278
279         ptr = _talloc(context, size);
280         if (ptr == NULL) {
281                 return NULL;
282         }
283
284         talloc_set_name_const(ptr, name);
285
286         return ptr;
287 }
288
289 /*
290   return the name of a talloc ptr, or "UNNAMED"
291 */
292 const char *talloc_get_name(const void *ptr)
293 {
294         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
295         if (tc->name) {
296                 return tc->name;
297         }
298         return "UNNAMED";
299 }
300
301 /*
302   this is for compatibility with older versions of talloc
303 */
304 void *talloc_init(const char *fmt, ...) _PRINTF_ATTRIBUTE(1,2)
305 {
306         va_list ap;
307         void *ptr;
308
309         ptr = _talloc(NULL, 0);
310         if (ptr == NULL) {
311                 return NULL;
312         }
313
314         va_start(ap, fmt);
315         talloc_set_name_v(ptr, fmt, ap);
316         va_end(ap);
317
318         return ptr;
319 }
320
321
322 /* 
323    free a talloc pointer. This also frees all child pointers of this 
324    pointer recursively
325
326    return 0 if the memory is actually freed, otherwise -1. The memory
327    will not be freed if the ref_count is > 1 or the destructor (if
328    any) returns non-zero
329 */
330 int talloc_free(void *ptr)
331 {
332         struct talloc_chunk *tc;
333
334         if (ptr == NULL) {
335                 return -1;
336         }
337
338         tc = talloc_chunk_from_ptr(ptr);
339
340         if (tc->refs) {
341                 talloc_reference_destructor(tc->refs);
342                 return 0;
343         }
344
345         if (tc->destructor) {
346                 talloc_destructor_t d = tc->destructor;
347                 if (d == (talloc_destructor_t)-1) {
348                         return -1;
349                 }
350                 tc->destructor = (talloc_destructor_t)-1;
351                 if (d(ptr) == -1) {
352                         tc->destructor = d;
353                         return -1;
354                 }
355                 tc->destructor = NULL;
356         }
357
358         while (tc->child) {
359                 /* we need to work out who will own an abandoned child
360                    if it cannot be freed. In priority order, the first
361                    choice is owner of any remaining reference to this
362                    pointer, the second choice is our parent, and the
363                    final choice is the null context. */
364                 void *child = tc->child+1;
365                 const void *new_parent = null_context;
366                 if (tc->child->refs) {
367                         struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
368                         if (p) new_parent = p+1;
369                 }
370                 if (new_parent == null_context) {
371                         struct talloc_chunk *p = talloc_parent_chunk(ptr);
372                         if (p) new_parent = p+1;
373                 }
374                 talloc_free(talloc_steal(new_parent, child));
375         }
376
377         if (tc->parent) {
378                 DLIST_REMOVE(tc->parent->child, tc);
379                 if (tc->parent->child) {
380                         tc->parent->child->parent = tc->parent;
381                 }
382         } else {
383                 if (tc->prev) tc->prev->next = tc->next;
384                 if (tc->next) tc->next->prev = tc->prev;
385         }
386
387         tc->magic = TALLOC_MAGIC_FREE;
388
389         free(tc);
390         return 0;
391 }
392
393
394
395 /*
396   A talloc version of realloc. The context argument is only used if
397   ptr is NULL
398 */
399 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
400 {
401         struct talloc_chunk *tc;
402         void *new_ptr;
403
404         /* size zero is equivalent to free() */
405         if (size == 0) {
406                 talloc_free(ptr);
407                 return NULL;
408         }
409
410         /* realloc(NULL) is equavalent to malloc() */
411         if (ptr == NULL) {
412                 return talloc_named_const(context, size, name);
413         }
414
415         tc = talloc_chunk_from_ptr(ptr);
416
417         /* don't allow realloc on referenced pointers */
418         if (tc->refs) {
419                 return NULL;
420         }
421
422         /* by resetting magic we catch users of the old memory */
423         tc->magic = TALLOC_MAGIC_FREE;
424
425         new_ptr = realloc(tc, size + sizeof(*tc));
426         if (!new_ptr) {
427                 tc->magic = TALLOC_MAGIC;
428                 return NULL;
429         }
430
431         tc = new_ptr;
432         tc->magic = TALLOC_MAGIC;
433         if (tc->parent) {
434                 tc->parent->child = new_ptr;
435         }
436
437         if (tc->prev) {
438                 tc->prev->next = tc;
439         }
440         if (tc->next) {
441                 tc->next->prev = tc;
442         }
443
444         tc->size = size;
445         talloc_set_name_const(tc+1, name);
446
447         return (void *)(tc+1);
448 }
449
450 /* 
451    move a lump of memory from one talloc context to another return the
452    ptr on success, or NULL if it could not be transferred
453 */
454 void *talloc_steal(const void *new_ctx, const void *ptr)
455 {
456         struct talloc_chunk *tc, *new_tc;
457
458         if (!ptr) {
459                 return NULL;
460         }
461
462         tc = talloc_chunk_from_ptr(ptr);
463
464         if (new_ctx == NULL) {
465                 if (tc->parent) {
466                         DLIST_REMOVE(tc->parent->child, tc);
467                         if (tc->parent->child) {
468                                 tc->parent->child->parent = tc->parent;
469                         }
470                 } else {
471                         if (tc->prev) tc->prev->next = tc->next;
472                         if (tc->next) tc->next->prev = tc->prev;
473                 }
474                 
475                 tc->parent = tc->next = tc->prev = NULL;
476                 return discard_const(ptr);
477         }
478
479         new_tc = talloc_chunk_from_ptr(new_ctx);
480
481         if (tc == new_tc) {
482                 return discard_const(ptr);
483         }
484
485         if (tc->parent) {
486                 DLIST_REMOVE(tc->parent->child, tc);
487                 if (tc->parent->child) {
488                         tc->parent->child->parent = tc->parent;
489                 }
490         } else {
491                 if (tc->prev) tc->prev->next = tc->next;
492                 if (tc->next) tc->next->prev = tc->prev;
493         }
494
495         tc->parent = new_tc;
496         if (new_tc->child) new_tc->child->parent = NULL;
497         DLIST_ADD(new_tc->child, tc);
498
499         return discard_const(ptr);
500 }
501
502 /*
503   return the total size of a talloc pool (subtree)
504 */
505 off_t talloc_total_size(const void *ptr)
506 {
507         off_t total = 0;
508         struct talloc_chunk *c, *tc;
509         
510         if (ptr == NULL) {
511                 ptr = null_context;
512         }
513         if (ptr == NULL) {
514                 return 0;
515         }
516
517         tc = talloc_chunk_from_ptr(ptr);
518
519         total = tc->size;
520         for (c=tc->child;c;c=c->next) {
521                 total += talloc_total_size(c+1);
522         }
523         return total;
524 }
525
526 /*
527   return the total number of blocks in a talloc pool (subtree)
528 */
529 off_t talloc_total_blocks(const void *ptr)
530 {
531         off_t total = 0;
532         struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
533
534         total++;
535         for (c=tc->child;c;c=c->next) {
536                 total += talloc_total_blocks(c+1);
537         }
538         return total;
539 }
540
541 /*
542   return the number of external references to a pointer
543 */
544 static int talloc_reference_count(const void *ptr)
545 {
546         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
547         struct talloc_reference_handle *h;
548         int ret = 0;
549
550         for (h=tc->refs;h;h=h->next) {
551                 ret++;
552         }
553         return ret;
554 }
555
556 /*
557   report on memory usage by all children of a pointer, giving a full tree view
558 */
559 static void talloc_report_depth(const void *ptr, FILE *f, int depth)
560 {
561         struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
562
563         for (c=tc->child;c;c=c->next) {
564                 const char *name = talloc_get_name(c+1);
565                 if (strcmp(name, ".reference") == 0) {
566                         struct talloc_reference_handle *handle = (void *)(c+1);
567                         const char *name2 = talloc_get_name(handle->ptr);
568                         fprintf(f, "%*sreference to: %s\n", depth*4, "", name2);
569                 } else {
570                         fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n", 
571                                 depth*4, "",
572                                 name,
573                                 (unsigned long)talloc_total_size(c+1),
574                                 (unsigned long)talloc_total_blocks(c+1),
575                                 talloc_reference_count(c+1));
576                         talloc_report_depth(c+1, f, depth+1);
577                 }
578         }
579
580 }
581
582 /*
583   report on memory usage by all children of a pointer, giving a full tree view
584 */
585 void talloc_report_full(const void *ptr, FILE *f)
586 {
587         if (ptr == NULL) {
588                 ptr = null_context;
589         }
590         if (ptr == NULL) return;
591
592         fprintf(f,"full talloc report on '%s' (total %lu bytes in %lu blocks)\n", 
593                 talloc_get_name(ptr), 
594                 (unsigned long)talloc_total_size(ptr),
595                 (unsigned long)talloc_total_blocks(ptr));
596
597         talloc_report_depth(ptr, f, 1);
598 }
599
600 /*
601   report on memory usage by all children of a pointer
602 */
603 void talloc_report(const void *ptr, FILE *f)
604 {
605         struct talloc_chunk *c, *tc;
606
607         if (ptr == NULL) {
608                 ptr = null_context;
609         }
610         if (ptr == NULL) return;
611        
612         fprintf(f,"talloc report on '%s' (total %lu bytes in %lu blocks)\n", 
613                 talloc_get_name(ptr), 
614                 (unsigned long)talloc_total_size(ptr),
615                 (unsigned long)talloc_total_blocks(ptr));
616
617         tc = talloc_chunk_from_ptr(ptr);
618
619         for (c=tc->child;c;c=c->next) {
620                 fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n", 
621                         talloc_get_name(c+1),
622                         (unsigned long)talloc_total_size(c+1),
623                         (unsigned long)talloc_total_blocks(c+1));
624         }
625
626 }
627
628 /*
629   report on any memory hanging off the null context
630 */
631 static void talloc_report_null(void)
632 {
633         if (talloc_total_size(null_context) == 0) {
634                 return;
635         }
636         talloc_report(null_context, stderr);
637 }
638
639 /*
640   report on any memory hanging off the null context
641 */
642 static void talloc_report_null_full(void)
643 {
644         if (talloc_total_size(null_context) == 0) {
645                 return;
646         }
647         talloc_report_full(null_context, stderr);
648 }
649
650 /*
651   enable leak reporting on exit
652 */
653 void talloc_enable_leak_report(void)
654 {
655         null_context = talloc_named_const(NULL, 0, "null_context");
656         atexit(talloc_report_null);
657 }
658
659 /*
660   enable full leak reporting on exit
661 */
662 void talloc_enable_leak_report_full(void)
663 {
664         null_context = talloc_named_const(NULL, 0, "null_context");
665         atexit(talloc_report_null_full);
666 }
667
668 /* 
669    talloc and zero memory. 
670 */
671 void *talloc_zero(const void *ctx, size_t size)
672 {
673         void *p = talloc(ctx, size);
674
675         if (p) {
676                 memset(p, '\0', size);
677         }
678
679         return p;
680 }
681
682
683 /*
684   memdup with a talloc. 
685 */
686 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
687 {
688         void *newp = talloc_named_const(t, size, name);
689
690         if (newp) {
691                 memcpy(newp, p, size);
692         }
693
694         return newp;
695 }
696
697 /*
698   strdup with a talloc 
699 */
700 char *talloc_strdup(const void *t, const char *p)
701 {
702         char *ret;
703         if (!p) {
704                 return NULL;
705         }
706         ret = talloc_memdup(t, p, strlen(p) + 1);
707         if (ret) {
708                 talloc_set_name_const(ret, ret);
709         }
710         return ret;
711 }
712
713 /*
714   strndup with a talloc 
715 */
716 char *talloc_strndup(const void *t, const char *p, size_t n)
717 {
718         size_t len = strnlen(p, n);
719         char *ret;
720
721         ret = talloc(t, len + 1);
722         if (!ret) { return NULL; }
723         memcpy(ret, p, len);
724         ret[len] = 0;
725         return ret;
726 }
727
728 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) _PRINTF_ATTRIBUTE(2,0)
729 {       
730         int len;
731         char *ret;
732         va_list ap2;
733         
734         VA_COPY(ap2, ap);
735
736         len = vsnprintf(NULL, 0, fmt, ap2);
737
738         ret = talloc(t, len+1);
739         if (ret) {
740                 VA_COPY(ap2, ap);
741                 vsnprintf(ret, len+1, fmt, ap2);
742                 talloc_set_name_const(ret, ret);
743         }
744
745         return ret;
746 }
747
748
749 /*
750   Perform string formatting, and return a pointer to newly allocated
751   memory holding the result, inside a memory pool.
752  */
753 char *talloc_asprintf(const void *t, const char *fmt, ...) _PRINTF_ATTRIBUTE(2,3)
754 {
755         va_list ap;
756         char *ret;
757
758         va_start(ap, fmt);
759         ret = talloc_vasprintf(t, fmt, ap);
760         va_end(ap);
761         return ret;
762 }
763
764
765 /**
766  * Realloc @p s to append the formatted result of @p fmt and @p ap,
767  * and return @p s, which may have moved.  Good for gradually
768  * accumulating output into a string buffer.
769  **/
770
771 static char *talloc_vasprintf_append(char *s,
772                                      const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
773
774 static char *talloc_vasprintf_append(char *s,
775                                      const char *fmt, va_list ap)
776 {       
777         int len, s_len;
778         va_list ap2;
779
780         VA_COPY(ap2, ap);
781
782         if (s) {
783                 s_len = strlen(s);
784         } else {
785                 s_len = 0;
786         }
787         len = vsnprintf(NULL, 0, fmt, ap2);
788
789         s = talloc_realloc(NULL, s, s_len + len+1);
790         if (!s) return NULL;
791
792         VA_COPY(ap2, ap);
793
794         vsnprintf(s+s_len, len+1, fmt, ap2);
795         talloc_set_name_const(s, s);
796
797         return s;
798 }
799
800 /*
801   Realloc @p s to append the formatted result of @p fmt and return @p
802   s, which may have moved.  Good for gradually accumulating output
803   into a string buffer.
804  */
805 char *talloc_asprintf_append(char *s,
806                              const char *fmt, ...) _PRINTF_ATTRIBUTE(2,3)
807 {
808         va_list ap;
809
810         va_start(ap, fmt);
811         s = talloc_vasprintf_append(s, fmt, ap);
812         va_end(ap);
813         return s;
814 }
815
816 /*
817   alloc an array, checking for integer overflow in the array size
818 */
819 void *talloc_array(const void *ctx, size_t el_size, uint_t count, const char *name)
820 {
821         if (count == 0 ||
822             count >= MAX_TALLOC_SIZE/el_size) {
823                 return NULL;
824         }
825         return talloc_named_const(ctx, el_size * count, name);
826 }
827
828
829 /*
830   realloc an array, checking for integer overflow in the array size
831 */
832 void *talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, uint_t count, const char *name)
833 {
834         if (count == 0 ||
835             count >= MAX_TALLOC_SIZE/el_size) {
836                 return NULL;
837         }
838         ptr = talloc_realloc(ctx, ptr, el_size * count);
839         if (ptr) {
840                 talloc_set_name_const(ptr, name);
841         }
842         return ptr;
843 }
844
845 /*
846   a alloc function for ldb that uses talloc
847 */
848 void *talloc_ldb_alloc(void *context, void *ptr, size_t size)
849 {
850         if (ptr == NULL) {
851                 return talloc(context, size);
852         }
853         if (size == 0) {
854                 talloc_free(ptr);
855                 return NULL;
856         }
857         return talloc_realloc(context, ptr, size);
858 }