aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2019-04-10 00:16:25 +0200
committerHarald Welte <laforge@gnumonks.org>2019-04-11 06:12:40 +0000
commit6b369a4cfd6500cd5b4e076bae1c1f91fbb05bb9 (patch)
tree2f30eaa8bf0371bcc42d04966a2e17ce940cc1af
parenta0e85ce237164de2dedd5d2dff56d9c2f10d28d2 (diff)
Allow application to override default heap allocator
Let's introduce a mechanism by which libsmpp34-using applications can override the memory allocator functions. This allows us e.g. in the Osmocom context to use talloc which aids us in debugging memory leaks. Closes: OS#3913 Change-Id: I3656117115e89638c093bfbcbc4369ce302f7a94
-rw-r--r--TODO-RELEASE1
-rw-r--r--src/Makefile.am2
-rw-r--r--src/smpp34_heap.c77
-rw-r--r--src/smpp34_heap.h15
-rw-r--r--src/smpp34_params.c19
-rw-r--r--src/smpp34_unpack.c7
6 files changed, 109 insertions, 12 deletions
diff --git a/TODO-RELEASE b/TODO-RELEASE
index d0852fc..bbc1495 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -7,3 +7,4 @@
# If any interfaces have been added since the last public release: c:r:a + 1.
# If any interfaces have been removed or changed since the last public release: c:r:0.
#library what description / commit summary line
+libsmpp34 smpp34_heap Adding new API/ABI to override memory allocator
diff --git a/src/Makefile.am b/src/Makefile.am
index 67550f3..55097c4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,6 +10,7 @@ libsmpp34_la_SOURCES = \
$(LIBRARY_SOURCE_DIR)/smpp34.h \
$(LIBRARY_SOURCE_DIR)/smpp34_dumpBuf.c \
$(LIBRARY_SOURCE_DIR)/smpp34_dumpPdu.c \
+ $(LIBRARY_SOURCE_DIR)/smpp34_heap.c \
$(LIBRARY_SOURCE_DIR)/smpp34_pack.c \
$(LIBRARY_SOURCE_DIR)/smpp34_unpack.c \
$(LIBRARY_SOURCE_DIR)/smpp34_structs.c \
@@ -19,6 +20,7 @@ libsmpp34_la_SOURCES = \
include_HEADERS = \
$(LIBRARY_SOURCE_DIR)/smpp34.h \
+ $(LIBRARY_SOURCE_DIR)/smpp34_heap.h \
$(LIBRARY_SOURCE_DIR)/smpp34_structs.h \
$(LIBRARY_SOURCE_DIR)/smpp34_params.h
diff --git a/src/smpp34_heap.c b/src/smpp34_heap.c
new file mode 100644
index 0000000..f93d457
--- /dev/null
+++ b/src/smpp34_heap.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2019 Harald Welte
+ * File : smpp34_heap.c
+ * Author: Harald Welte <laforge@gnumonks.org>
+ *
+ * This file is part of libsmpp34 (c-open-smpp3.4 library).
+ *
+ * The libsmpp34 library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include "smpp34_heap.h"
+
+static void *smpp34_libc_malloc(size_t sz)
+{
+ return malloc(sz);
+}
+
+static void *smpp34_libc_realloc(void *ptr, size_t sz)
+{
+ return realloc(ptr, sz);
+}
+
+static void smpp34_libc_free(void *ptr)
+{
+ return free(ptr);
+}
+
+static bool allocator_used = false;
+
+static struct smpp34_memory_functions smpp34_allocator = {
+ .malloc_fun = smpp34_libc_malloc,
+ .realloc_fun = smpp34_libc_realloc,
+ .free_fun = smpp34_libc_free,
+};
+
+void smpp34_set_memory_functions(const struct smpp34_memory_functions *mf)
+{
+ if (allocator_used) {
+ fprintf(stderr, "%s must be called before first use of smpp34_malloc\n", __func__);
+ return;
+ }
+ smpp34_allocator = *mf;
+}
+
+void *smpp34_malloc(size_t sz)
+{
+ allocator_used = true;
+ return smpp34_allocator.malloc_fun(sz);
+}
+
+void *smpp34_realloc(void *ptr, size_t sz)
+{
+ allocator_used = true;
+ return smpp34_allocator.realloc_fun(ptr, sz);
+}
+
+void smpp34_free(void *ptr)
+{
+ smpp34_allocator.free_fun(ptr);
+}
diff --git a/src/smpp34_heap.h b/src/smpp34_heap.h
new file mode 100644
index 0000000..6b9ac42
--- /dev/null
+++ b/src/smpp34_heap.h
@@ -0,0 +1,15 @@
+#pragma once
+#include <stddef.h>
+
+/* override the allocator with these methods; to be called BEFORE allocating anything */
+struct smpp34_memory_functions {
+ void * (*malloc_fun)(size_t sz);
+ void * (*realloc_fun)(void *ptr, size_t sz);
+ void (*free_fun)(void *ptr);
+};
+
+void smpp34_set_memory_functions(const struct smpp34_memory_functions *mf);
+
+void *smpp34_malloc(size_t sz);
+void *smpp34_realloc(void *ptr, size_t sz);
+void smpp34_free(void *ptr);
diff --git a/src/smpp34_params.c b/src/smpp34_params.c
index a91f9eb..e7eb680 100644
--- a/src/smpp34_params.c
+++ b/src/smpp34_params.c
@@ -27,15 +27,16 @@
#include "smpp34.h"
#include "smpp34_structs.h"
+#include "smpp34_heap.h"
int
build_udad( udad_t **dest, udad_t *source )
{
/* Build new DAD-Chain ************************************************/
- udad_t *dummy = (udad_t*)malloc(sizeof( udad_t ));
+ udad_t *dummy = (udad_t*)smpp34_malloc(sizeof( udad_t ));
if( dummy == NULL ){
- printf("Error in malloc()\n" );
+ printf("Error in smpp34_malloc()\n" );
return( -1 );
};
memcpy(dummy, source, sizeof( udad_t ));
@@ -54,7 +55,7 @@ destroy_udad( udad_t *sourceList )
/* Destroy DAD-Chain **************************************************/
while( sourceList != NULL ){
i = sourceList->next;
- free((void*)sourceList);
+ smpp34_free((void*)sourceList);
sourceList = i;
};
@@ -68,9 +69,9 @@ build_dad( dad_t **dest, dad_t *source )
{
/* Build new DAD-Chain ************************************************/
- dad_t *dummy = (dad_t*)malloc(sizeof( dad_t ));
+ dad_t *dummy = (dad_t*)smpp34_malloc(sizeof( dad_t ));
if( dummy == NULL ){
- printf("Error in malloc()\n" );
+ printf("Error in smpp34_malloc()\n" );
return( -1 );
};
memcpy(dummy, source, sizeof( dad_t ));
@@ -89,7 +90,7 @@ destroy_dad( dad_t *sourceList )
/* Destroy DAD-Chain **************************************************/
while( sourceList != NULL ){
i = sourceList->next;
- free((void*)sourceList);
+ smpp34_free((void*)sourceList);
sourceList = i;
};
@@ -102,9 +103,9 @@ build_tlv( tlv_t **dest, tlv_t *source )
{
/* Build new TLV-Chain ************************************************/
- tlv_t *dummy = (tlv_t*)malloc(sizeof( tlv_t ));
+ tlv_t *dummy = (tlv_t*)smpp34_malloc(sizeof( tlv_t ));
if( dummy == NULL ){
- printf("Error in malloc()\n" );
+ printf("Error in smpp34_malloc()\n" );
return( -1 );
};
memcpy(dummy, source, sizeof( tlv_t ));
@@ -123,7 +124,7 @@ destroy_tlv( tlv_t *sourceList )
/* Destroy TLV-Chain **************************************************/
while( sourceList != NULL ){
i = sourceList->next;
- free((void*)sourceList);
+ smpp34_free((void*)sourceList);
sourceList = i;
};
diff --git a/src/smpp34_unpack.c b/src/smpp34_unpack.c
index 749a037..ec73d35 100644
--- a/src/smpp34_unpack.c
+++ b/src/smpp34_unpack.c
@@ -31,6 +31,7 @@
#include "smpp34.h"
#include "smpp34_structs.h"
#include "smpp34_params.h"
+#include "smpp34_heap.h"
/* GLOBALS ********************************************************************/
/* EXTERN *********************************************************************/
@@ -179,7 +180,7 @@ smpp34_unpack(uint32_t type, void* tt, const uint8_t *ptrBuf, int ptrLen)
#define TLV( inst, tlv3, do_tlv ){\
tlv_t *aux_tlv = NULL;\
while( (aux - ini) < t1->command_length ){\
- aux_tlv = (tlv_t *) malloc(sizeof( tlv_t ));\
+ aux_tlv = (tlv_t *) smpp34_malloc(sizeof( tlv_t ));\
memset(aux_tlv, 0, sizeof(tlv_t));\
do_tlv( aux_tlv );\
aux_tlv->next = inst tlv3;\
@@ -191,7 +192,7 @@ smpp34_unpack(uint32_t type, void* tt, const uint8_t *ptrBuf, int ptrLen)
udad_t *aux_udad = NULL;\
int c = 0;\
while( c < t1->no_unsuccess ){\
- aux_udad = (udad_t *) malloc(sizeof( udad_t ));\
+ aux_udad = (udad_t *) smpp34_malloc(sizeof( udad_t ));\
memset(aux_udad, 0, sizeof(udad_t));\
do_udad( aux_udad );\
aux_udad->next = inst udad3;\
@@ -204,7 +205,7 @@ smpp34_unpack(uint32_t type, void* tt, const uint8_t *ptrBuf, int ptrLen)
dad_t *aux_dad = NULL;\
int c = 0;\
while( c < t1->number_of_dests ){\
- aux_dad = (dad_t *) malloc(sizeof( dad_t ));\
+ aux_dad = (dad_t *) smpp34_malloc(sizeof( dad_t ));\
memset(aux_dad, 0, sizeof(dad_t));\
do_dad( aux_dad );\
aux_dad->next = inst dad3;\