summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2006-05-24 07:31:02 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:08:32 -0500
commita665cccd2ef81e704e90bb228bbd14c0afb031af (patch)
tree20ff8949a797c3435e586c12148f1a8aed9c731c
parent574daba7951b64b6b877db55a92e5a66f3354b4f (diff)
downloadsamba-a665cccd2ef81e704e90bb228bbd14c0afb031af.tar.gz
samba-a665cccd2ef81e704e90bb228bbd14c0afb031af.tar.bz2
samba-a665cccd2ef81e704e90bb228bbd14c0afb031af.zip
r15852: patch from Rusty to make talloc_set_destructor() and talloc_steal()
type safe. This only works on recent gcc versions. With other compilers it reverts to a non-typesafe cast The patch also ensures that talloc_free() does not change error on systems where free() can change errno (This used to be commit babbff5f777642f559747f6d0697bc7c3a5e798d)
-rw-r--r--source4/lib/talloc/talloc.c14
-rw-r--r--source4/lib/talloc/talloc.h47
-rw-r--r--source4/lib/talloc/testsuite.c2
3 files changed, 40 insertions, 23 deletions
diff --git a/source4/lib/talloc/talloc.c b/source4/lib/talloc/talloc.c
index 67478fc9d4..b34369cb16 100644
--- a/source4/lib/talloc/talloc.c
+++ b/source4/lib/talloc/talloc.c
@@ -30,12 +30,12 @@
inspired by http://swapped.cc/halloc/
*/
-
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
@@ -218,7 +218,7 @@ void *_talloc(const void *context, size_t size)
if the destructor fails then the free is failed, and the memory can
be continued to be used
*/
-void talloc_set_destructor(const void *ptr, int (*destructor)(void *))
+void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
{
struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
tc->destructor = destructor;
@@ -235,10 +235,9 @@ void talloc_increase_ref_count(const void *ptr)
/*
helper for talloc_reference()
*/
-static int talloc_reference_destructor(void *ptr)
+static int talloc_reference_destructor(struct talloc_reference_handle *handle)
{
- struct talloc_reference_handle *handle = ptr;
- struct talloc_chunk *tc1 = talloc_chunk_from_ptr(ptr);
+ struct talloc_chunk *tc1 = talloc_chunk_from_ptr(handle);
struct talloc_chunk *tc2 = talloc_chunk_from_ptr(handle->ptr);
if (tc1->destructor != (talloc_destructor_t)-1) {
tc1->destructor = NULL;
@@ -534,6 +533,7 @@ void talloc_free_children(void *ptr)
int talloc_free(void *ptr)
{
struct talloc_chunk *tc;
+ int old_errno;
if (ptr == NULL) {
return -1;
@@ -586,7 +586,9 @@ int talloc_free(void *ptr)
tc->flags |= TALLOC_FLAG_FREE;
+ old_errno = errno;
free(tc);
+ errno = old_errno;
return 0;
}
@@ -667,7 +669,7 @@ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *n
ptr on success, or NULL if it could not be transferred.
passing NULL as ptr will always return NULL with no side effects.
*/
-void *talloc_steal(const void *new_ctx, const void *ptr)
+void *_talloc_steal(const void *new_ctx, const void *ptr)
{
struct talloc_chunk *tc, *new_tc;
diff --git a/source4/lib/talloc/talloc.h b/source4/lib/talloc/talloc.h
index 99410241a6..be2b305753 100644
--- a/source4/lib/talloc/talloc.h
+++ b/source4/lib/talloc/talloc.h
@@ -40,6 +40,34 @@ typedef void TALLOC_CTX;
#define TALLOC_DEPRECATED 0
#endif
+#ifndef PRINTF_ATTRIBUTE
+#if (__GNUC__ >= 3)
+/** Use gcc attribute to check printf fns. a1 is the 1-based index of
+ * the parameter containing the format, and a2 the index of the first
+ * argument. Note that some gcc 2.x versions don't handle this
+ * properly **/
+#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
+#else
+#define PRINTF_ATTRIBUTE(a1, a2)
+#endif
+#endif
+
+/* try to make talloc_set_destructor() and talloc_steal() type safe,
+ if we have a recent gcc */
+#if (__GNUC__ >= 3)
+#define _TALLOC_TYPEOF(ptr) __typeof__(ptr)
+#define talloc_set_destructor(ptr, function) \
+ do { \
+ int (*_talloc_destructor_fn)(typeof(ptr)) = (function); \
+ _talloc_set_destructor((ptr), (void *)_talloc_destructor_fn); \
+ } while(0)
+#define _TALLOC_CHECK_TYPE(type,val)
+#else
+#define talloc_set_destructor(ptr, function) \
+ _talloc_set_destructor((ptr), (int (*)(void *))(function))
+#define _TALLOC_TYPEOF(ptr) void *
+#endif
+
/* useful macros for creating type checked pointers */
#define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type)
#define talloc_size(ctx, size) talloc_named_const(ctx, size, __location__)
@@ -70,7 +98,7 @@ typedef void TALLOC_CTX;
#define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type)
#define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type)
-
+#define talloc_steal(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_steal((ctx),(ptr))
#if TALLOC_DEPRECATED
#define talloc_zero_p(ctx, type) talloc_zero(ctx, type)
@@ -80,22 +108,9 @@ typedef void TALLOC_CTX;
#define talloc_destroy(ctx) talloc_free(ctx)
#endif
-#ifndef PRINTF_ATTRIBUTE
-#if (__GNUC__ >= 3)
-/** Use gcc attribute to check printf fns. a1 is the 1-based index of
- * the parameter containing the format, and a2 the index of the first
- * argument. Note that some gcc 2.x versions don't handle this
- * properly **/
-#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
-#else
-#define PRINTF_ATTRIBUTE(a1, a2)
-#endif
-#endif
-
-
/* The following definitions come from talloc.c */
void *_talloc(const void *context, size_t size);
-void talloc_set_destructor(const void *ptr, int (*destructor)(void *));
+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);
int talloc_unlink(const void *context, void *ptr);
@@ -111,7 +126,7 @@ void *talloc_parent(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);
+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);
diff --git a/source4/lib/talloc/testsuite.c b/source4/lib/talloc/testsuite.c
index 018d734cc3..f1b19041fa 100644
--- a/source4/lib/talloc/testsuite.c
+++ b/source4/lib/talloc/testsuite.c
@@ -850,7 +850,7 @@ static BOOL test_lifeless(void)
static int loop_destructor_count;
-static int test_loop_destructor(void *ptr)
+static int test_loop_destructor(char *ptr)
{
printf("loop destructor\n");
loop_destructor_count++;