libwbclient: Add wbcAllocateMemory()
authorVolker Lendecke <vl@samba.org>
Tue, 6 Apr 2010 20:10:22 +0000 (22:10 +0200)
committerVolker Lendecke <vl@samba.org>
Mon, 19 Apr 2010 12:27:16 +0000 (14:27 +0200)
This prepares for removing libwbclient's talloc dependency. It is a
non-hierarchical "talloc-lite" that has destructors. It is necessary because we
have the catch-call wbcFreeMemory call. Individual wbcFreeXXX calls for the
different structures wbclient returns would have made this easier, but
wbcFreeMemory is the API we have to live with.

nsswitch/libwbclient/wbclient.c
nsswitch/libwbclient/wbclient_internal.h

index cd5ffa876afd90c590ab8e0882b041647a74a32b..6b076ad499d0e6a021c61c93015fe73e010d41df 100644 (file)
@@ -147,12 +147,61 @@ const char *wbcErrorString(wbcErr error)
        return "unknown wbcErr value";
 }
 
+#define WBC_MAGIC (0x7a2b0e1e)
+
+struct wbcMemPrefix {
+       uint32_t magic;
+       void (*destructor)(void *ptr);
+};
+
+static size_t wbcPrefixLen(void)
+{
+       size_t result = sizeof(struct wbcMemPrefix);
+       return (result + 15) & ~15;
+}
+
+static struct wbcMemPrefix *wbcMemToPrefix(void *ptr)
+{
+       return (struct wbcMemPrefix *)(((char *)ptr) - wbcPrefixLen());
+}
+
+void *wbcAllocateMemory(size_t nelem, size_t elsize,
+                       void (*destructor)(void *ptr))
+{
+       struct wbcMemPrefix *result;
+
+       if (nelem >= (2<<24)/elsize) {
+               /* basic protection against integer wrap */
+               return NULL;
+       }
+
+       result = (struct wbcMemPrefix *)calloc(
+               1, nelem*elsize + wbcPrefixLen());
+       if (result == NULL) {
+               return NULL;
+       }
+       result->magic = WBC_MAGIC;
+       result->destructor = destructor;
+       return ((char *)result) + wbcPrefixLen();
+}
+
 /* Free library allocated memory */
 void wbcFreeMemory(void *p)
 {
-       if (p)
-               talloc_free(p);
+       struct wbcMemPrefix *wbcMem;
 
+       if (p == NULL) {
+               return;
+       }
+       wbcMem = wbcMemToPrefix(p);
+       if (wbcMem->magic != WBC_MAGIC) {
+               talloc_free(p);
+               return;
+       }
+       if (wbcMem->destructor != NULL) {
+               wbcMem->destructor(p);
+       }
+       free(wbcMem);
        return;
 }
 
index 5ce820785eef57ac73557b4da636767c467ad3c5..6c59be3fef87cf426127753b557679bfa0240e66 100644 (file)
@@ -32,4 +32,7 @@ wbcErr wbcRequestResponsePriv(int cmd,
                              struct winbindd_request *request,
                              struct winbindd_response *response);
 
+void *wbcAllocateMemory(size_t nelem, size_t elsize,
+                       void (*destructor)(void *ptr));
+
 #endif      /* _WBCLIENT_INTERNAL_H */