r3553: Allow talloc_reference to take a NULL pointer for the "ptr" argument.
authorAndrew Bartlett <abartlet@samba.org>
Fri, 5 Nov 2004 12:20:27 +0000 (12:20 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:05:31 +0000 (13:05 -0500)
This allows potentially NULL pointers to be referenced, without an if ()
for every use.  (previously, it would segfault).

Update doco, and allow talloc_unlink to match.

Andrew Bartlett
(This used to be commit 59757c7f9d0e08e3acacfb3116f6205057d5b119)

source4/lib/talloc.c
source4/torture/local/talloc.c
talloc_guide.txt

index 131edfcb817170fa5d6e39023e03f9464b34bd55..239958258bbed688ee5198a01f7bb87cb687c66a 100644 (file)
@@ -222,9 +222,13 @@ static int talloc_reference_destructor(void *ptr)
 */
 void *talloc_reference(const void *context, const void *ptr)
 {
-       struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
+       struct talloc_chunk *tc;
        struct talloc_reference_handle *handle;
+       if (ptr == NULL) return NULL;
+
+       tc = talloc_chunk_from_ptr(ptr);
        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
@@ -273,6 +277,10 @@ int talloc_unlink(const void *context, void *ptr)
        struct talloc_chunk *tc_p, *new_p;
        void *new_parent;
 
+       if (ptr == NULL) {
+               return -1;
+       }
+
        if (context == NULL) {
                context = null_context;
        }
index 348b037753adb200557659ada5a38e5faf3f4366..2eedb2b9b08fea813d556aedceda2667b6cfd4d8 100644 (file)
@@ -117,6 +117,11 @@ static BOOL test_ref1(void)
        talloc_free(r1);
        talloc_report_full(NULL, stdout);
 
+       printf("Testing NULL\n");
+       if (talloc_reference(root, NULL)) {
+               return False;
+       }
+
        CHECK_BLOCKS(root, 1);
 
        CHECK_SIZE(root, 0);
@@ -478,7 +483,12 @@ static BOOL test_misc(void)
        talloc_unlink(NULL, p2);
        talloc_unlink(root, p1);
 
-       
+       /* Test that talloc_unlink is a no-op */
+
+       if (talloc_unlink(root, NULL) != -1) {
+               printf("failed: talloc_unlink(root, NULL) == -1\n");
+               return False;
+       }
 
        talloc_report(root, stdout);
        talloc_report(NULL, stdout);
index a794cdffbe51cae1cf09a3773e553132cd627654..b3b148d4768b6d8adf619fee76ecaa313d8682e7 100644 (file)
@@ -122,6 +122,8 @@ The return value of talloc_reference() is always the original pointer
 which case it will return NULL (each additional reference consumes
 around 48 bytes of memory on intel x86 platforms).
 
+If "ptr" is NULL, then the function is a no-op, and simply returns NULL.
+
 After creating a reference you can free it in one of the following
 ways:
 
@@ -144,7 +146,8 @@ context passed must either be a context used in talloc_reference()
 with this pointer, or must be a direct parent of ptr. 
 
 Note that if the parent has already been removed using talloc_free()
-then this function will fail and will return -1.
+then this function will fail and will return -1.  Likewise, if "ptr"
+is NULL, then the function will make no modifications and return -1.
 
 Usually you can just use talloc_free() instead of talloc_unlink(), but
 sometimes it is useful to have the additional control on which parent