summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/lib/talloc/configure.ac2
-rw-r--r--source3/lib/talloc/talloc.c233
-rw-r--r--source3/lib/talloc/talloc.h26
-rw-r--r--source3/lib/talloc/testsuite.c48
4 files changed, 184 insertions, 125 deletions
diff --git a/source3/lib/talloc/configure.ac b/source3/lib/talloc/configure.ac
index 5f465fe93a..afc2a944f0 100644
--- a/source3/lib/talloc/configure.ac
+++ b/source3/lib/talloc/configure.ac
@@ -1,5 +1,5 @@
AC_PREREQ(2.50)
-AC_INIT(talloc, 1.0)
+AC_INIT(talloc, 1.1.0)
AC_CONFIG_SRCDIR([talloc.c])
AC_SUBST(datarootdir)
AC_CONFIG_HEADER(config.h)
diff --git a/source3/lib/talloc/talloc.c b/source3/lib/talloc/talloc.c
index 7920a66d64..4d72c0e871 100644
--- a/source3/lib/talloc/talloc.c
+++ b/source3/lib/talloc/talloc.c
@@ -1109,64 +1109,132 @@ void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name
return newp;
}
+static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
+{
+ char *ret;
+
+ ret = (char *)__talloc(t, len + 1);
+ if (unlikely(!ret)) return NULL;
+
+ memcpy(ret, p, len);
+ ret[len] = 0;
+
+ _talloc_set_name_const(ret, ret);
+ return ret;
+}
+
/*
- strdup with a talloc
+ strdup with a talloc
*/
char *talloc_strdup(const void *t, const char *p)
{
+ if (unlikely(!p)) return NULL;
+ return __talloc_strlendup(t, p, strlen(p));
+}
+
+/*
+ strndup with a talloc
+*/
+char *talloc_strndup(const void *t, const char *p, size_t n)
+{
+ if (unlikely(!p)) return NULL;
+ return __talloc_strlendup(t, p, strnlen(p, n));
+}
+
+static inline char *__talloc_strlendup_append(char *s, size_t slen,
+ const char *a, size_t alen)
+{
char *ret;
- if (!p) {
- return NULL;
+
+ ret = talloc_realloc(NULL, s, char, slen + alen + 1);
+ if (unlikely(!ret)) return NULL;
+
+ /* append the string and the trailing \0 */
+ memcpy(&ret[slen], a, alen);
+ ret[slen+alen] = 0;
+
+ _talloc_set_name_const(ret, ret);
+ return ret;
+}
+
+/*
+ * Appends at the end of the string.
+ */
+char *talloc_strdup_append(char *s, const char *a)
+{
+ if (unlikely(!s)) {
+ return talloc_strdup(NULL, a);
}
- ret = (char *)talloc_memdup(t, p, strlen(p) + 1);
- if (likely(ret)) {
- _talloc_set_name_const(ret, ret);
+
+ if (unlikely(!a)) {
+ return s;
}
- return ret;
+
+ return __talloc_strlendup_append(s, strlen(s), a, strlen(a));
}
/*
- append to a talloced string
-*/
-char *talloc_append_string(const void *t, char *orig, const char *append)
+ * Appends at the end of the talloc'ed buffer,
+ * not the end of the string.
+ */
+char *talloc_strdup_append_buffer(char *s, const char *a)
{
- char *ret;
- size_t olen = strlen(orig);
- size_t alenz;
+ size_t slen;
- if (!append)
- return orig;
+ if (unlikely(!s)) {
+ return talloc_strdup(NULL, a);
+ }
- alenz = strlen(append) + 1;
+ if (unlikely(!a)) {
+ return s;
+ }
- ret = talloc_realloc(t, orig, char, olen + alenz);
- if (!ret)
- return NULL;
+ slen = talloc_get_size(s);
+ if (likely(slen > 0)) {
+ slen--;
+ }
- /* append the string with the trailing \0 */
- memcpy(&ret[olen], append, alenz);
+ return __talloc_strlendup_append(s, slen, a, strlen(a));
+}
- _talloc_set_name_const(ret, ret);
+/*
+ * Appends at the end of the string.
+ */
+char *talloc_strndup_append(char *s, const char *a, size_t n)
+{
+ if (unlikely(!s)) {
+ return talloc_strdup(NULL, a);
+ }
- return ret;
+ if (unlikely(!a)) {
+ return s;
+ }
+
+ return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n));
}
/*
- strndup with a talloc
-*/
-char *talloc_strndup(const void *t, const char *p, size_t n)
+ * Appends at the end of the talloc'ed buffer,
+ * not the end of the string.
+ */
+char *talloc_strndup_append_buffer(char *s, const char *a, size_t n)
{
- size_t len;
- char *ret;
+ size_t slen;
- for (len=0; len<n && p[len]; len++) ;
+ if (unlikely(!s)) {
+ return talloc_strdup(NULL, a);
+ }
- ret = (char *)__talloc(t, len + 1);
- if (!ret) { return NULL; }
- memcpy(ret, p, len);
- ret[len] = 0;
- _talloc_set_name_const(ret, ret);
- return ret;
+ if (unlikely(!a)) {
+ return s;
+ }
+
+ slen = talloc_get_size(s);
+ if (likely(slen > 0)) {
+ slen--;
+ }
+
+ return __talloc_strlendup_append(s, slen, a, strnlen(a, n));
}
#ifndef HAVE_VA_COPY
@@ -1188,18 +1256,18 @@ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
va_copy(ap2, ap);
len = vsnprintf(&c, 1, fmt, ap2);
va_end(ap2);
- if (len < 0) {
+ if (unlikely(len < 0)) {
return NULL;
}
ret = (char *)__talloc(t, len+1);
- if (ret) {
- va_copy(ap2, ap);
- vsnprintf(ret, len+1, fmt, ap2);
- va_end(ap2);
- _talloc_set_name_const(ret, ret);
- }
+ if (unlikely(!ret)) return NULL;
+ va_copy(ap2, ap);
+ vsnprintf(ret, len+1, fmt, ap2);
+ va_end(ap2);
+
+ _talloc_set_name_const(ret, ret);
return ret;
}
@@ -1219,30 +1287,22 @@ char *talloc_asprintf(const void *t, const char *fmt, ...)
return ret;
}
+static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
+ const char *fmt, va_list ap)
+ PRINTF_ATTRIBUTE(3,0);
-/**
- * Realloc @p s to append the formatted result of @p fmt and @p ap,
- * and return @p s, which may have moved. Good for gradually
- * accumulating output into a string buffer. Appends at the end
- * of the string.
- **/
-char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
+static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
+ const char *fmt, va_list ap)
{
- int len, s_len;
+ ssize_t alen;
va_list ap2;
char c;
- if (s == NULL) {
- return talloc_vasprintf(NULL, fmt, ap);
- }
-
- s_len = strlen(s);
-
va_copy(ap2, ap);
- len = vsnprintf(&c, 1, fmt, ap2);
+ alen = vsnprintf(&c, 1, fmt, ap2);
va_end(ap2);
- if (len <= 0) {
+ if (alen <= 0) {
/* Either the vsnprintf failed or the format resulted in
* no characters being formatted. In the former case, we
* ought to return NULL, in the latter we ought to return
@@ -1252,60 +1312,51 @@ char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
return s;
}
- s = talloc_realloc(NULL, s, char, s_len + len+1);
+ s = talloc_realloc(NULL, s, char, slen + alen + 1);
if (!s) return NULL;
va_copy(ap2, ap);
- vsnprintf(s+s_len, len+1, fmt, ap2);
+ vsnprintf(s + slen, alen + 1, fmt, ap2);
va_end(ap2);
- _talloc_set_name_const(s, s);
+ _talloc_set_name_const(s, s);
return s;
}
/**
* Realloc @p s to append the formatted result of @p fmt and @p ap,
+ * and return @p s, which may have moved. Good for gradually
+ * accumulating output into a string buffer. Appends at the end
+ * of the string.
+ **/
+char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
+{
+ if (unlikely(!s)) {
+ return talloc_vasprintf(NULL, fmt, ap);
+ }
+
+ return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap);
+}
+
+/**
+ * Realloc @p s to append the formatted result of @p fmt and @p ap,
* and return @p s, which may have moved. Always appends at the
* end of the talloc'ed buffer, not the end of the string.
**/
char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap)
{
- struct talloc_chunk *tc;
- int len, s_len;
- va_list ap2;
- char c;
+ size_t slen;
- if (s == NULL) {
+ if (unlikely(!s)) {
return talloc_vasprintf(NULL, fmt, ap);
}
- tc = talloc_chunk_from_ptr(s);
-
- s_len = tc->size - 1;
-
- va_copy(ap2, ap);
- len = vsnprintf(&c, 1, fmt, ap2);
- va_end(ap2);
-
- if (len <= 0) {
- /* Either the vsnprintf failed or the format resulted in
- * no characters being formatted. In the former case, we
- * ought to return NULL, in the latter we ought to return
- * the original string. Most current callers of this
- * function expect it to never return NULL.
- */
- return s;
+ slen = talloc_get_size(s);
+ if (likely(slen > 0)) {
+ slen--;
}
- s = talloc_realloc(NULL, s, char, s_len + len+1);
- if (!s) return NULL;
-
- va_copy(ap2, ap);
- vsnprintf(s+s_len, len+1, fmt, ap2);
- va_end(ap2);
- _talloc_set_name_const(s, s);
-
- return s;
+ return __talloc_vaslenprintf_append(s, slen, fmt, ap);
}
/*
diff --git a/source3/lib/talloc/talloc.h b/source3/lib/talloc/talloc.h
index 95152a1416..e103391681 100644
--- a/source3/lib/talloc/talloc.h
+++ b/source3/lib/talloc/talloc.h
@@ -111,6 +111,7 @@ typedef void TALLOC_CTX;
#define talloc_array_p(ctx, type, count) talloc_array(ctx, type, count)
#define talloc_realloc_p(ctx, p, type, count) talloc_realloc(ctx, p, type, count)
#define talloc_destroy(ctx) talloc_free(ctx)
+#define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a))
#endif
/* The following definitions come from talloc.c */
@@ -152,15 +153,6 @@ void talloc_enable_leak_report(void);
void talloc_enable_leak_report_full(void);
void *_talloc_zero(const void *ctx, size_t size, const char *name);
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_append_string(const void *t, char *orig, const char *append);
-char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
-char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
-char *talloc_vasprintf_append_buffer(char *s, 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);
-char *talloc_asprintf_append_buffer(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_zero_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);
@@ -171,4 +163,20 @@ void *talloc_find_parent_byname(const void *ctx, const char *name);
void talloc_show_parents(const void *context, FILE *file);
int talloc_is_parent(const void *context, const void *ptr);
+char *talloc_strdup(const void *t, const char *p);
+char *talloc_strdup_append(char *s, const char *a);
+char *talloc_strdup_append_buffer(char *s, const char *a);
+
+char *talloc_strndup(const void *t, const char *p, size_t n);
+char *talloc_strndup_append(char *s, const char *a, size_t n);
+char *talloc_strndup_append_buffer(char *s, const char *a, size_t n);
+
+char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
+char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
+char *talloc_vasprintf_append_buffer(char *s, 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);
+char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
+
#endif
diff --git a/source3/lib/talloc/testsuite.c b/source3/lib/talloc/testsuite.c
index 2e3ae65082..e16c91f8b9 100644
--- a/source3/lib/talloc/testsuite.c
+++ b/source3/lib/talloc/testsuite.c
@@ -106,7 +106,7 @@ static bool test_ref1(void)
{
void *root, *p1, *p2, *ref, *r1;
- printf("test: ref1 [\nSINGLE REFERENCE FREE\n]\n");
+ printf("test: ref1\n# SINGLE REFERENCE FREE\n");
root = talloc_named_const(NULL, 0, "root");
p1 = talloc_named_const(root, 1, "p1");
@@ -162,7 +162,7 @@ static bool test_ref2(void)
{
void *root, *p1, *p2, *ref, *r1;
- printf("test: ref2 [\nDOUBLE REFERENCE FREE\n]\n");
+ printf("test: ref2\n# DOUBLE REFERENCE FREE\n");
root = talloc_named_const(NULL, 0, "root");
p1 = talloc_named_const(root, 1, "p1");
talloc_named_const(p1, 1, "x1");
@@ -217,7 +217,7 @@ static bool test_ref3(void)
{
void *root, *p1, *p2, *ref, *r1;
- printf("test: ref3 [\nPARENT REFERENCE FREE\n]\n");
+ printf("test: ref3\n# PARENT REFERENCE FREE\n");
root = talloc_named_const(NULL, 0, "root");
p1 = talloc_named_const(root, 1, "p1");
@@ -256,7 +256,7 @@ static bool test_ref4(void)
{
void *root, *p1, *p2, *ref, *r1;
- printf("test: ref4 [\nREFERRER REFERENCE FREE\n]\n");
+ printf("test: ref4\n# REFERRER REFERENCE FREE\n");
root = talloc_named_const(NULL, 0, "root");
p1 = talloc_named_const(root, 1, "p1");
@@ -306,7 +306,7 @@ static bool test_unlink1(void)
{
void *root, *p1, *p2, *ref, *r1;
- printf("test: unlink [\nUNLINK\n]\n");
+ printf("test: unlink\n# UNLINK\n");
root = talloc_named_const(NULL, 0, "root");
p1 = talloc_named_const(root, 1, "p1");
@@ -358,7 +358,7 @@ static bool test_misc(void)
double *d;
const char *name;
- printf("test: misc [\nMISCELLANEOUS\n]\n");
+ printf("test: misc\n# MISCELLANEOUS\n");
root = talloc_new(NULL);
@@ -419,15 +419,15 @@ static bool test_misc(void)
p2 = talloc_strndup(p1, "foo", 2);
torture_assert("misc", strcmp("fo", p2) == 0,
"strndup doesn't work\n");
- p2 = talloc_asprintf_append(p2, "o%c", 'd');
+ p2 = talloc_asprintf_append_buffer(p2, "o%c", 'd');
torture_assert("misc", strcmp("food", p2) == 0,
- "talloc_asprintf_append doesn't work\n");
+ "talloc_asprintf_append_buffer doesn't work\n");
CHECK_BLOCKS("misc", p2, 1);
CHECK_BLOCKS("misc", p1, 3);
- p2 = talloc_asprintf_append(NULL, "hello %s", "world");
+ p2 = talloc_asprintf_append_buffer(NULL, "hello %s", "world");
torture_assert("misc", strcmp("hello world", p2) == 0,
- "talloc_asprintf_append doesn't work\n");
+ "talloc_asprintf_append_buffer doesn't work\n");
CHECK_BLOCKS("misc", p2, 1);
CHECK_BLOCKS("misc", p1, 3);
talloc_free(p2);
@@ -509,7 +509,7 @@ static bool test_realloc(void)
{
void *root, *p1, *p2;
- printf("test: realloc [\nREALLOC\n]\n");
+ printf("test: realloc\n# REALLOC\n");
root = talloc_new(NULL);
@@ -553,7 +553,7 @@ static bool test_realloc(void)
talloc_free(root);
- printf("success: REALLOC\n");
+ printf("success: realloc\n");
return true;
}
@@ -617,7 +617,7 @@ static bool test_type(void)
};
struct el1 *el1;
- printf("test: type [\ntalloc type checking\n]\n");
+ printf("test: type\n# talloc type checking\n");
root = talloc_new(NULL);
@@ -646,7 +646,7 @@ static bool test_steal(void)
{
void *root, *p1, *p2;
- printf("test: steal [\nSTEAL\n]\n");
+ printf("test: steal\n# STEAL\n");
root = talloc_new(NULL);
@@ -702,7 +702,7 @@ static bool test_move(void)
int *x;
} *t1, *t2;
- printf("test: move [\nMOVE\n]\n");
+ printf("test: move\n# MOVE\n");
root = talloc_new(NULL);
@@ -732,7 +732,7 @@ static bool test_realloc_fn(void)
{
void *root, *p1;
- printf("test: realloc_fn [\ntalloc_realloc_fn\n]\n");
+ printf("test: realloc_fn\n# talloc_realloc_fn\n");
root = talloc_new(NULL);
@@ -757,7 +757,7 @@ static bool test_unref_reparent(void)
{
void *root, *p1, *p2, *c1;
- printf("test: unref_reparent [\nUNREFERENCE AFTER PARENT FREED\n]\n");
+ printf("test: unref_reparent\n# UNREFERENCE AFTER PARENT FREED\n");
root = talloc_named_const(NULL, 0, "root");
p1 = talloc_named_const(root, 1, "orig parent");
@@ -794,7 +794,7 @@ static bool test_speed(void)
int i;
struct timeval tv;
- printf("test: speed [\nTALLOC VS MALLOC SPEED\n]\n");
+ printf("test: speed\n# TALLOC VS MALLOC SPEED\n");
tv = timeval_current();
count = 0;
@@ -840,7 +840,7 @@ static bool test_lifeless(void)
char *parent, *child;
void *child_owner = talloc_new(NULL);
- printf("test: lifeless [\nTALLOC_UNLINK LOOP\n]\n");
+ printf("test: lifeless\n# TALLOC_UNLINK LOOP\n");
parent = talloc_strdup(top, "parent");
child = talloc_strdup(parent, "child");
@@ -874,7 +874,7 @@ static bool test_loop(void)
char *req2, *req3;
} *req1;
- printf("test: loop [\nTALLOC LOOP DESTRUCTION\n]\n");
+ printf("test: loop\n# TALLOC LOOP DESTRUCTION\n");
parent = talloc_strdup(top, "parent");
req1 = talloc(parent, struct req1);
@@ -908,7 +908,7 @@ static bool test_free_parent_deny_child(void)
char *level2;
char *level3;
- printf("test: free_parent_deny_child [\nTALLOC FREE PARENT DENY CHILD\n]\n");
+ printf("test: free_parent_deny_child\n# TALLOC FREE PARENT DENY CHILD\n");
level1 = talloc_strdup(top, "level1");
level2 = talloc_strdup(level1, "level2");
@@ -938,7 +938,7 @@ static bool test_talloc_ptrtype(void)
const char *location3;
const char *location4;
- printf("test: ptrtype [\nTALLOC PTRTYPE\n]\n");
+ printf("test: ptrtype\n# TALLOC PTRTYPE\n");
s1 = talloc_ptrtype(top, s1);location1 = __location__;
@@ -1024,7 +1024,7 @@ static bool test_talloc_free_in_destructor(void)
void *level4;
void **level5;
- printf("test: free_in_destructor [\nTALLOC FREE IN DESTRUCTOR\n]\n");
+ printf("test: free_in_destructor\n# TALLOC FREE IN DESTRUCTOR\n");
level0 = talloc_new(NULL);
level1 = talloc_new(level0);
@@ -1053,7 +1053,7 @@ static bool test_autofree(void)
#if _SAMBA_BUILD_ < 4
/* autofree test would kill smbtorture */
void *p;
- printf("test: autofree [\nTALLOC AUTOFREE CONTEXT\n]\n");
+ printf("test: autofree\n# TALLOC AUTOFREE CONTEXT\n");
p = talloc_autofree_context();
talloc_free(p);