summaryrefslogtreecommitdiff
path: root/nsswitch/libwbclient/wbclient.c
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2010-04-06 22:10:22 +0200
committerVolker Lendecke <vl@samba.org>2010-04-19 14:27:16 +0200
commitf2a04a0ccb7276dcd23efeade59368540c6570b2 (patch)
treef9111fc59545f07df81cf68a332714251aa069a8 /nsswitch/libwbclient/wbclient.c
parent456351cdb184f59374cecec8d7c44add29b986dd (diff)
downloadsamba-f2a04a0ccb7276dcd23efeade59368540c6570b2.tar.gz
samba-f2a04a0ccb7276dcd23efeade59368540c6570b2.tar.bz2
samba-f2a04a0ccb7276dcd23efeade59368540c6570b2.zip
libwbclient: Add wbcAllocateMemory()
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.
Diffstat (limited to 'nsswitch/libwbclient/wbclient.c')
-rw-r--r--nsswitch/libwbclient/wbclient.c53
1 files changed, 51 insertions, 2 deletions
diff --git a/nsswitch/libwbclient/wbclient.c b/nsswitch/libwbclient/wbclient.c
index cd5ffa876a..6b076ad499 100644
--- a/nsswitch/libwbclient/wbclient.c
+++ b/nsswitch/libwbclient/wbclient.c
@@ -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;
}