summaryrefslogtreecommitdiffstats
path: root/libxtables
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2020-05-05 13:56:11 +0200
committerPhil Sutter <phil@nwl.cc>2020-05-11 14:28:29 +0200
commit7db4333dc0b6cd8e943fab78d6dab40ff9f4512e (patch)
tree351ee8f17a1b795dced28f65f04e43681eef9499 /libxtables
parent869e38fcdecda3de35d999b75fbaacc750fe3aaa (diff)
libxtables: Introduce xtables_fini()
Record handles of loaded shared objects in a linked list and dlclose() them from the newly introduced function. While functionally not necessary, this clears up valgrind's memcheck output when also displaying reachable memory. Since this is an extra function that doesn't change the existing API, increment both current and age. Signed-off-by: Phil Sutter <phil@nwl.cc>
Diffstat (limited to 'libxtables')
-rw-r--r--libxtables/xtables.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
index 777c2b08..7fe42580 100644
--- a/libxtables/xtables.c
+++ b/libxtables/xtables.c
@@ -206,6 +206,38 @@ struct xtables_target *xtables_targets;
static bool xtables_fully_register_pending_match(struct xtables_match *me);
static bool xtables_fully_register_pending_target(struct xtables_target *me);
+/* registry for loaded shared objects to close later */
+struct dlreg {
+ struct dlreg *next;
+ void *handle;
+};
+static struct dlreg *dlreg = NULL;
+
+static int dlreg_add(void *handle)
+{
+ struct dlreg *new = malloc(sizeof(*new));
+
+ if (!new)
+ return -1;
+
+ new->handle = handle;
+ new->next = dlreg;
+ dlreg = new;
+ return 0;
+}
+
+static void dlreg_free(void)
+{
+ struct dlreg *next;
+
+ while (dlreg) {
+ next = dlreg->next;
+ dlclose(dlreg->handle);
+ free(dlreg);
+ dlreg = next;
+ }
+}
+
void xtables_init(void)
{
xtables_libdir = getenv("XTABLES_LIBDIR");
@@ -233,6 +265,11 @@ void xtables_init(void)
xtables_libdir = XTABLES_LIBDIR;
}
+void xtables_fini(void)
+{
+ dlreg_free();
+}
+
void xtables_set_nfproto(uint8_t nfproto)
{
switch (nfproto) {
@@ -567,6 +604,8 @@ static void *load_extension(const char *search_path, const char *af_prefix,
next = dir + strlen(dir);
for (prefix = all_prefixes; *prefix != NULL; ++prefix) {
+ void *handle;
+
snprintf(path, sizeof(path), "%.*s/%s%s.so",
(unsigned int)(next - dir), dir,
*prefix, name);
@@ -578,11 +617,14 @@ static void *load_extension(const char *search_path, const char *af_prefix,
strerror(errno));
return NULL;
}
- if (dlopen(path, RTLD_NOW) == NULL) {
+ handle = dlopen(path, RTLD_NOW);
+ if (handle == NULL) {
fprintf(stderr, "%s: %s\n", path, dlerror());
break;
}
+ dlreg_add(handle);
+
if (is_target)
ptr = xtables_find_target(name, XTF_DONT_LOAD);
else