#define data_blob(ptr, size) data_blob_named(ptr, size, __location__)
#define data_blob_talloc(ctx, ptr, size) data_blob_talloc_named(ctx, ptr, size, __location__)
+#ifndef PRINTF_ATTRIBUTE
+#define PRINTF_ATTRIBUTE(a1, a2)
+#endif
+
+
+/* The following definitions come from lib/talloc.c */
+void *_talloc(const void *context, size_t size);
+void talloc_set_destructor(const void *ptr, int (*destructor)(void *));
+void talloc_increase_ref_count(const void *ptr);
+void *talloc_reference(const void *context, const void *ptr);
+void *talloc_unreference(const void *context, const void *ptr);
+void talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
+void talloc_set_name_const(const void *ptr, const char *name);
+void *talloc_named(const void *context, size_t size,
+ const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
+void *talloc_named_const(const void *context, size_t size, const char *name);
+const char *talloc_get_name(const void *ptr);
+void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
+int talloc_free(void *ptr);
+void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name);
+void *talloc_steal(const void *new_ctx, const void *ptr);
+off_t talloc_total_size(const void *ptr);
+off_t talloc_total_blocks(const void *ptr);
+void talloc_report_full(const void *ptr, FILE *f);
+void talloc_report(const void *ptr, FILE *f);
+void talloc_enable_leak_report(void);
+void talloc_enable_leak_report_full(void);
+void *talloc_zero(const void *ctx, size_t size);
+void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name);
+char *talloc_strdup(const void *t, const char *p);
+char *talloc_strndup(const void *t, const char *p, size_t n);
+char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
+char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
+char *talloc_asprintf_append(char *s,
+ const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
+void *talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name);
+void *talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name);
+void *talloc_ldb_alloc(void *context, void *ptr, size_t size);
+
#endif
/*
Samba Unix SMB/CIFS implementation.
- Samba temporary memory allocation functions - new interface
+ Samba trivial allocation library - new interface
+
+ NOTE: Please read talloc_guide.txt for full documentation
Copyright (C) Andrew Tridgell 2004
inspired by http://swapped.cc/halloc/
*/
+
+/*
+ if you need to build this outside of the Samba source tree then please define _STANDALONE_
+*/
+#ifdef _STANDALONE_
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include "talloc.h"
+#else
#include "includes.h"
+#endif
#define MAX_TALLOC_SIZE 0x10000000
#define TALLOC_MAGIC 0xe814ec4f
#define TALLOC_MAGIC_FREE 0x7faebef3
+#define TALLOC_MAGIC_REFERENCE ((const char *)1)
+/* by default we abort when given a bad pointer (such as when talloc_free() is called
+ on a pointer that came from malloc() */
+#ifndef TALLOC_ABORT
+#define TALLOC_ABORT(reason) abort()
+#endif
+
+#ifndef discard_const_p
+#define discard_const_p(type, ptr) ((type *)(ptr))
+#endif
+
+/* this null_context is only used if talloc_enable_leak_report() or
+ talloc_enable_leak_report_full() is called, otherwise it remains
+ NULL
+*/
static const void *null_context;
+
struct talloc_reference_handle {
struct talloc_reference_handle *next, *prev;
void *ptr;
struct talloc_chunk *parent, *child;
struct talloc_reference_handle *refs;
size_t size;
- uint_t magic;
+ unsigned magic;
talloc_destructor_t destructor;
const char *name;
};
/* panic if we get a bad magic value */
static struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
{
- struct talloc_chunk *tc = ((struct talloc_chunk *)discard_const(ptr))-1;
- if (tc->magic != TALLOC_MAGIC) {
+ struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, ptr)-1;
+ if (tc->magic != TALLOC_MAGIC) {
if (tc->magic == TALLOC_MAGIC_FREE) {
- smb_panic("Bad talloc magic value - double free\n");
+ TALLOC_ABORT("Bad talloc magic value - double free");
} else {
- smb_panic("Bad talloc magic value\n");
+ TALLOC_ABORT("Bad talloc magic value - unknown value");
}
}
+
return tc;
}
+/* hook into the front of the list */
+#define _TLIST_ADD(list, p) \
+do { \
+ if (!(list)) { \
+ (list) = (p); \
+ (p)->next = (p)->prev = NULL; \
+ } else { \
+ (list)->prev = (p); \
+ (p)->next = (list); \
+ (p)->prev = NULL; \
+ (list) = (p); \
+ }\
+} while (0)
+
+/* remove an element from a list - element doesn't have to be in list. */
+#define _TLIST_REMOVE(list, p) \
+do { \
+ if ((p) == (list)) { \
+ (list) = (p)->next; \
+ if (list) (list)->prev = NULL; \
+ } else { \
+ if ((p)->prev) (p)->prev->next = (p)->next; \
+ if ((p)->next) (p)->next->prev = (p)->prev; \
+ } \
+ if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
+} while (0)
+
/*
return the parent chunk of a pointer
}
tc = malloc(sizeof(*tc)+size);
- if (tc == NULL) {
- return NULL;
- }
+ if (tc == NULL) return NULL;
tc->size = size;
tc->magic = TALLOC_MAGIC;
parent->child->parent = NULL;
}
- DLIST_ADD(parent->child, tc);
+ _TLIST_ADD(parent->child, tc);
} else {
tc->next = tc->prev = tc->parent = NULL;
}
if (tc1->destructor != (talloc_destructor_t)-1) {
tc1->destructor = NULL;
}
- DLIST_REMOVE(tc2->refs, handle);
+ _TLIST_REMOVE(tc2->refs, handle);
talloc_free(handle);
return 0;
}
{
struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
struct talloc_reference_handle *handle;
- handle = talloc_named_const(context, sizeof(*handle), ".reference");
- if (handle == NULL) {
- return NULL;
- }
+ handle = talloc_named_const(context, sizeof(*handle), TALLOC_MAGIC_REFERENCE);
+ if (handle == NULL) return NULL;
+
/* note that we hang the destructor off the handle, not the
main context as that allows the caller to still setup their
own destructor on the context if they want to */
talloc_set_destructor(handle, talloc_reference_destructor);
- handle->ptr = discard_const(ptr);
- DLIST_ADD(tc->refs, handle);
+ handle->ptr = discard_const_p(void, ptr);
+ _TLIST_ADD(tc->refs, handle);
return handle->ptr;
}
}
talloc_set_destructor(h, NULL);
- DLIST_REMOVE(tc->refs, h);
+ _TLIST_REMOVE(tc->refs, h);
talloc_free(h);
- return discard_const(ptr);
+ return discard_const_p(void, ptr);
}
/*
/*
add a name to an existing pointer
*/
-void talloc_set_name(const void *ptr, const char *fmt, ...) _PRINTF_ATTRIBUTE(2,3)
+void talloc_set_name(const void *ptr, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
talloc_named() operates just like talloc() except that it allows you
to name the pointer.
*/
-void *talloc_named(const void *context, size_t size,
- const char *fmt, ...) _PRINTF_ATTRIBUTE(3,4)
+void *talloc_named(const void *context, size_t size, const char *fmt, ...)
{
va_list ap;
void *ptr;
ptr = _talloc(context, size);
- if (ptr == NULL) {
- return NULL;
- }
+ if (ptr == NULL) return NULL;
va_start(ap, fmt);
talloc_set_name_v(ptr, fmt, ap);
const char *talloc_get_name(const void *ptr)
{
struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
+ if (tc->name == TALLOC_MAGIC_REFERENCE) {
+ return ".reference";
+ }
if (tc->name) {
return tc->name;
}
/*
this is for compatibility with older versions of talloc
*/
-void *talloc_init(const char *fmt, ...) _PRINTF_ATTRIBUTE(1,2)
+void *talloc_init(const char *fmt, ...)
{
va_list ap;
void *ptr;
ptr = _talloc(NULL, 0);
- if (ptr == NULL) {
- return NULL;
- }
+ if (ptr == NULL) return NULL;
va_start(ap, fmt);
talloc_set_name_v(ptr, fmt, ap);
}
if (tc->parent) {
- DLIST_REMOVE(tc->parent->child, tc);
+ _TLIST_REMOVE(tc->parent->child, tc);
if (tc->parent->child) {
tc->parent->child->parent = tc->parent;
}
return NULL;
}
+ if (size >= MAX_TALLOC_SIZE) {
+ return NULL;
+ }
+
/* realloc(NULL) is equavalent to malloc() */
if (ptr == NULL) {
return talloc_named_const(context, size, name);
tc->magic = TALLOC_MAGIC_FREE;
new_ptr = realloc(tc, size + sizeof(*tc));
- if (!new_ptr) {
- tc->magic = TALLOC_MAGIC;
- return NULL;
+ if (!new_ptr) {
+ tc->magic = TALLOC_MAGIC;
+ return NULL;
}
tc = new_ptr;
if (new_ctx == NULL) {
if (tc->parent) {
- DLIST_REMOVE(tc->parent->child, tc);
+ _TLIST_REMOVE(tc->parent->child, tc);
if (tc->parent->child) {
tc->parent->child->parent = tc->parent;
}
}
tc->parent = tc->next = tc->prev = NULL;
- return discard_const(ptr);
+ return discard_const_p(void, ptr);
}
new_tc = talloc_chunk_from_ptr(new_ctx);
if (tc == new_tc) {
- return discard_const(ptr);
+ return discard_const_p(void, ptr);
}
if (tc->parent) {
- DLIST_REMOVE(tc->parent->child, tc);
+ _TLIST_REMOVE(tc->parent->child, tc);
if (tc->parent->child) {
tc->parent->child->parent = tc->parent;
}
tc->parent = new_tc;
if (new_tc->child) new_tc->child->parent = NULL;
- DLIST_ADD(new_tc->child, tc);
+ _TLIST_ADD(new_tc->child, tc);
- return discard_const(ptr);
+ return discard_const_p(void, ptr);
}
/*
struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
for (c=tc->child;c;c=c->next) {
- const char *name = talloc_get_name(c+1);
- if (strcmp(name, ".reference") == 0) {
+ if (c->name == TALLOC_MAGIC_REFERENCE) {
struct talloc_reference_handle *handle = (void *)(c+1);
const char *name2 = talloc_get_name(handle->ptr);
fprintf(f, "%*sreference to: %s\n", depth*4, "", name2);
} else {
+ const char *name = talloc_get_name(c+1);
fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n",
depth*4, "",
name,
*/
static void talloc_report_null(void)
{
- if (talloc_total_size(null_context) == 0) {
- return;
+ if (talloc_total_size(null_context) != 0) {
+ talloc_report(null_context, stderr);
}
- talloc_report(null_context, stderr);
}
/*
*/
static void talloc_report_null_full(void)
{
- if (talloc_total_size(null_context) == 0) {
- return;
+ if (talloc_total_size(null_context) != 0) {
+ talloc_report_full(null_context, stderr);
}
- talloc_report_full(null_context, stderr);
}
/*
*/
char *talloc_strndup(const void *t, const char *p, size_t n)
{
- size_t len = strnlen(p, n);
+ size_t len;
char *ret;
+ for (len=0; p[len] && len<n; len++) ;
+
ret = talloc(t, len + 1);
if (!ret) { return NULL; }
memcpy(ret, p, len);
return ret;
}
-char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) _PRINTF_ATTRIBUTE(2,0)
+#ifndef VA_COPY
+#ifdef HAVE_VA_COPY
+#define VA_COPY(dest, src) __va_copy(dest, src)
+#else
+#define VA_COPY(dest, src) (dest) = (src)
+#endif
+#endif
+
+char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
{
int len;
char *ret;
Perform string formatting, and return a pointer to newly allocated
memory holding the result, inside a memory pool.
*/
-char *talloc_asprintf(const void *t, const char *fmt, ...) _PRINTF_ATTRIBUTE(2,3)
+char *talloc_asprintf(const void *t, const char *fmt, ...)
{
va_list ap;
char *ret;
* accumulating output into a string buffer.
**/
-static char *talloc_vasprintf_append(char *s,
- const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
+static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
-static char *talloc_vasprintf_append(char *s,
- const char *fmt, va_list ap)
+static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
{
int len, s_len;
va_list ap2;
s, which may have moved. Good for gradually accumulating output
into a string buffer.
*/
-char *talloc_asprintf_append(char *s,
- const char *fmt, ...) _PRINTF_ATTRIBUTE(2,3)
+char *talloc_asprintf_append(char *s, const char *fmt, ...)
{
va_list ap;
/*
alloc an array, checking for integer overflow in the array size
*/
-void *talloc_array(const void *ctx, size_t el_size, uint_t count, const char *name)
+void *talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
{
if (count == 0 ||
count >= MAX_TALLOC_SIZE/el_size) {
/*
realloc an array, checking for integer overflow in the array size
*/
-void *talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, uint_t count, const char *name)
+void *talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
{
if (count == 0 ||
count >= MAX_TALLOC_SIZE/el_size) {
#define CHECK_BLOCKS(ptr, tblocks) do { \
if (talloc_total_blocks(ptr) != (tblocks)) { \
- printf("(%d) failed: wrong '%s' tree size: got %u expected %u\n", \
- __LINE__, #ptr, \
+ printf(__location__ " failed: wrong '%s' tree blocks: got %u expected %u\n", \
+ #ptr, \
(unsigned)talloc_total_blocks(ptr), \
(unsigned)tblocks); \
talloc_report_full(ptr, stdout); \
} \
} while (0)
+#define CHECK_SIZE(ptr, tsize) do { \
+ if (talloc_total_size(ptr) != (tsize)) { \
+ printf(__location__ " failed: wrong '%s' tree size: got %u expected %u\n", \
+ #ptr, \
+ (unsigned)talloc_total_size(ptr), \
+ (unsigned)tsize); \
+ talloc_report_full(ptr, stdout); \
+ return False; \
+ } \
+} while (0)
+
/*
test references
*/
CHECK_BLOCKS(root, 1);
- if (talloc_total_size(root) != 0) {
- printf("failed: non-zero total size\n");
- return False;
- }
+ CHECK_SIZE(root, 0);
talloc_free(root);
talloc_free(r1);
talloc_report_full(root, stdout);
- if (talloc_total_size(root) != 0) {
- printf("failed: non-zero total size\n");
- return False;
- }
+ CHECK_SIZE(root, 0);
talloc_free(root);
talloc_free(p2);
talloc_report_full(root, stdout);
- if (talloc_total_size(root) != 0) {
- printf("failed: non-zero total size\n");
- return False;
- }
+ CHECK_SIZE(root, 0);
talloc_free(root);
talloc_free(p1);
talloc_report_full(root, stdout);
- if (talloc_total_size(root) != 0) {
- printf("failed: non-zero total size\n");
- return False;
- }
+ CHECK_SIZE(root, 0);
talloc_free(root);
talloc_free(p1);
talloc_report_full(root, stdout);
- if (talloc_total_size(root) != 0) {
- printf("failed: non-zero total size\n");
+ CHECK_SIZE(root, 0);
+
+ talloc_free(root);
+
+ return True;
+}
+
+static int fail_destructor(void *ptr)
+{
+ return -1;
+}
+
+/*
+ miscellaneous tests to try to get a higher test coverage percentage
+*/
+static BOOL test_misc(void)
+{
+ void *root, *p1;
+ char *p2;
+ double *d;
+
+ printf("TESTING MISCELLANEOUS\n");
+
+ root = talloc(NULL, 0);
+
+ p1 = talloc(root, 0x7fffffff);
+ if (p1) {
+ printf("failed: large talloc allowed\n");
+ return False;
+ }
+
+ p1 = talloc_strdup(root, "foo");
+ talloc_increase_ref_count(p1);
+ talloc_increase_ref_count(p1);
+ talloc_increase_ref_count(p1);
+ CHECK_BLOCKS(p1, 1);
+ CHECK_BLOCKS(root, 2);
+ talloc_free(p1);
+ CHECK_BLOCKS(p1, 1);
+ CHECK_BLOCKS(root, 2);
+ talloc_unreference(NULL, p1);
+ CHECK_BLOCKS(p1, 1);
+ CHECK_BLOCKS(root, 2);
+ if (talloc_unreference(root, p1) != NULL) {
+ printf("failed: talloc_unreference() of non-reference context should return NULL\n");
+ return False;
+ }
+ talloc_free(p1);
+ CHECK_BLOCKS(p1, 1);
+ CHECK_BLOCKS(root, 2);
+
+ talloc_set_name(p1, "my name is %s", "foo");
+ if (strcmp(talloc_get_name(p1), "my name is foo") != 0) {
+ printf("failed: wrong name after talloc_set_name\n");
+ return False;
+ }
+ CHECK_BLOCKS(p1, 2);
+ CHECK_BLOCKS(root, 3);
+
+ talloc_set_name_const(p1, NULL);
+ if (strcmp(talloc_get_name(p1), "UNNAMED") != 0) {
+ printf("failed: wrong name after talloc_set_name(NULL)\n");
+ return False;
+ }
+ CHECK_BLOCKS(p1, 2);
+ CHECK_BLOCKS(root, 3);
+
+
+ if (talloc_free(NULL) != -1) {
+ printf("talloc_free(NULL) should give -1\n");
+ return False;
+ }
+
+ talloc_set_destructor(p1, fail_destructor);
+ if (talloc_free(p1) != -1) {
+ printf("Failed destructor should cause talloc_free to fail\n");
+ return False;
+ }
+ talloc_set_destructor(p1, NULL);
+
+ talloc_report(root, stdout);
+
+
+ p2 = talloc_zero(p1, 20);
+ if (p2[19] != 0) {
+ printf("Failed to give zero memory\n");
+ return False;
+ }
+ talloc_free(p2);
+
+ if (talloc_strdup(root, NULL) != NULL) {
+ printf("failed: strdup on NULL should give NULL\n");
+ return False;
+ }
+
+ p2 = talloc_strndup(p1, "foo", 2);
+ if (strcmp("fo", p2) != 0) {
+ printf("failed: strndup doesn't work\n");
+ return False;
+ }
+ p2 = talloc_asprintf_append(p2, "o%c", 'd');
+ if (strcmp("food", p2) != 0) {
+ printf("failed: talloc_asprintf_append doesn't work\n");
+ return False;
+ }
+ CHECK_BLOCKS(p2, 1);
+ CHECK_BLOCKS(p1, 3);
+
+ p2 = talloc_asprintf_append(NULL, "hello %s", "world");
+ if (strcmp("hello world", p2) != 0) {
+ printf("failed: talloc_asprintf_append doesn't work\n");
+ return False;
+ }
+ CHECK_BLOCKS(p2, 1);
+ CHECK_BLOCKS(p1, 3);
+ talloc_free(p2);
+
+ d = talloc_array_p(p1, double, 0x20000000);
+ if (d) {
+ printf("failed: integer overflow not detected\n");
+ return False;
+ }
+
+ d = talloc_realloc_p(p1, d, double, 0x20000000);
+ if (d) {
+ printf("failed: integer overflow not detected\n");
+ return False;
+ }
+
+ talloc_free(p1);
+ CHECK_BLOCKS(root, 1);
+
+ talloc_report(root, stdout);
+ talloc_report(NULL, stdout);
+
+ CHECK_SIZE(root, 0);
+
+ talloc_free(root);
+
+ CHECK_SIZE(NULL, 0);
+
+ talloc_enable_leak_report();
+ talloc_enable_leak_report_full();
+
+ return True;
+}
+
+
+/*
+ test realloc
+*/
+static BOOL test_realloc(void)
+{
+ void *root, *p1, *p2;
+
+ printf("TESTING REALLOC\n");
+
+ root = talloc(NULL, 0);
+
+ p1 = talloc(root, 10);
+ CHECK_SIZE(p1, 10);
+
+ p1 = talloc_realloc(NULL, p1, 20);
+ CHECK_SIZE(p1, 20);
+
+ talloc(p1, 0);
+
+ p2 = talloc_realloc(p1, NULL, 30);
+
+ talloc(p1, 0);
+
+ p2 = talloc_realloc(p1, p2, 40);
+
+ CHECK_SIZE(p2, 40);
+ CHECK_SIZE(root, 60);
+ CHECK_BLOCKS(p1, 4);
+
+ p1 = talloc_realloc(NULL, p1, 20);
+ CHECK_SIZE(p1, 60);
+
+ talloc_increase_ref_count(p2);
+ if (talloc_realloc(NULL, p2, 5) != NULL) {
+ printf("failed: talloc_realloc() on a referenced pointer should fail\n");
return False;
}
+ CHECK_BLOCKS(p1, 4);
+
+ talloc_realloc(NULL, p2, 0);
+ talloc_realloc(NULL, p2, 0);
+ CHECK_BLOCKS(p1, 3);
+
+ if (talloc_realloc(NULL, p1, 0x7fffffff) != NULL) {
+ printf("failed: oversize talloc should fail\n");
+ return False;
+ }
+
+ talloc_realloc(NULL, p1, 0);
+
+ CHECK_BLOCKS(root, 1);
+ CHECK_SIZE(root, 0);
talloc_free(root);
return True;
}
+/*
+ test steal
+*/
+static BOOL test_steal(void)
+{
+ void *root, *p1, *p2;
+
+ printf("TESTING STEAL\n");
+
+ root = talloc(NULL, 0);
+
+ p1 = talloc_array_p(root, char, 10);
+ CHECK_SIZE(p1, 10);
+
+ p2 = talloc_realloc_p(root, NULL, char, 20);
+ CHECK_SIZE(p1, 10);
+ CHECK_SIZE(root, 30);
+
+ if (talloc_steal(p1, NULL) != NULL) {
+ printf("failed: stealing NULL should give NULL\n");
+ return False;
+ }
+
+ if (talloc_steal(p1, p1) != p1) {
+ printf("failed: stealing to ourselves is a nop\n");
+ return False;
+ }
+ CHECK_BLOCKS(root, 3);
+ CHECK_SIZE(root, 30);
+
+ talloc_steal(NULL, p1);
+ talloc_steal(NULL, p2);
+ CHECK_BLOCKS(root, 1);
+ CHECK_SIZE(root, 0);
+
+ talloc_free(p1);
+ talloc_steal(root, p2);
+ CHECK_BLOCKS(root, 2);
+ CHECK_SIZE(root, 20);
+
+ talloc_free(p2);
+
+ CHECK_BLOCKS(root, 1);
+ CHECK_SIZE(root, 0);
+
+ talloc_free(root);
+
+ p1 = talloc(NULL, 3);
+ CHECK_SIZE(NULL, 3);
+ talloc_free(p1);
+
+ return True;
+}
+
+/*
+ test ldb alloc fn
+*/
+static BOOL test_ldb(void)
+{
+ void *root, *p1;
+
+ printf("TESTING LDB\n");
+
+ root = talloc(NULL, 0);
+
+ p1 = talloc_ldb_alloc(root, NULL, 10);
+ CHECK_BLOCKS(root, 2);
+ CHECK_SIZE(root, 10);
+ p1 = talloc_ldb_alloc(root, p1, 20);
+ CHECK_BLOCKS(root, 2);
+ CHECK_SIZE(root, 20);
+ p1 = talloc_ldb_alloc(root, p1, 0);
+ CHECK_BLOCKS(root, 1);
+ CHECK_SIZE(root, 0);
+
+ talloc_free(root);
+
+
+ return True;
+}
+
/*
measure the speed of talloc versus malloc
*/
ret &= test_ref3();
ret &= test_ref4();
ret &= test_unref1();
+ ret &= test_misc();
+ ret &= test_realloc();
+ ret &= test_steal();
+ ret &= test_ldb();
ret &= test_speed();
return ret;