diff options
author | Volker Lendecke <vl@samba.org> | 2010-04-06 22:10:22 +0200 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2010-04-19 14:27:16 +0200 |
commit | f2a04a0ccb7276dcd23efeade59368540c6570b2 (patch) | |
tree | f9111fc59545f07df81cf68a332714251aa069a8 /nsswitch | |
parent | 456351cdb184f59374cecec8d7c44add29b986dd (diff) | |
download | samba-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')
-rw-r--r-- | nsswitch/libwbclient/wbclient.c | 53 | ||||
-rw-r--r-- | nsswitch/libwbclient/wbclient_internal.h | 3 |
2 files changed, 54 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; } diff --git a/nsswitch/libwbclient/wbclient_internal.h b/nsswitch/libwbclient/wbclient_internal.h index 5ce820785e..6c59be3fef 100644 --- a/nsswitch/libwbclient/wbclient_internal.h +++ b/nsswitch/libwbclient/wbclient_internal.h @@ -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 */ |