]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
library: Add facility to register custom init/deinit functions
authorTobias Brunner <tobias@strongswan.org>
Fri, 28 Mar 2025 12:49:56 +0000 (13:49 +0100)
committerTobias Brunner <tobias@strongswan.org>
Thu, 10 Apr 2025 06:31:09 +0000 (08:31 +0200)
These can be linked into the application to do initialization/cleanup
without having to modify the source code.

src/libstrongswan/library.c
src/libstrongswan/library.h

index bfc55d4cc8d659787a83083386c3b098ef466c35..a102ae43c89c3a957733b7947760225c55486c40 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009-2018 Tobias Brunner
+ * Copyright (C) 2009-2025 Tobias Brunner
  * Copyright (C) 2008 Martin Willi
  *
  * Copyright (C) secunet Security Networks AG
@@ -95,6 +95,30 @@ void library_add_namespace(char *ns)
        }
 }
 
+#define MAX_LIBSTRONGSWAN_INIT_FUNCTIONS 10
+
+/**
+ * Static array for init function registration using __attribute__((constructor))
+ */
+static library_init_t init_functions[MAX_LIBSTRONGSWAN_INIT_FUNCTIONS];
+static int init_function_count;
+
+/**
+ * Described in header
+ */
+void library_init_register(library_init_t init)
+{
+       if (init_function_count < MAX_LIBSTRONGSWAN_INIT_FUNCTIONS - 1)
+       {
+               init_functions[init_function_count++] = init;
+       }
+       else
+       {
+               fprintf(stderr, "failed to register init function, please increase "
+                               "MAX_LIBSTRONGSWAN_INIT_FUNCTIONS");
+       }
+}
+
 /**
  * Register plugins if built statically
  */
@@ -149,6 +173,7 @@ void library_deinit()
 {
        private_library_t *this = (private_library_t*)lib;
        bool detailed;
+       int i;
 
        if (!this || !ref_put(&this->ref))
        {       /* have more users */
@@ -161,6 +186,11 @@ void library_deinit()
        /* make sure the cache is clear before unloading plugins */
        lib->credmgr->flush_cache(lib->credmgr, CERT_ANY);
 
+       for (i = 0; i < init_function_count; ++i)
+       {
+               init_functions[i](FALSE);
+       }
+
        key_exchange_deinit();
 
        this->public.streams->destroy(this->public.streams);
@@ -441,5 +471,12 @@ bool library_init(char *settings, const char *namespace)
 
        key_exchange_init();
 
+       for (i = 0; i < init_function_count; ++i)
+       {
+               if (!init_functions[i](TRUE))
+               {
+                       this->init_failed = TRUE;
+               }
+       }
        return !this->init_failed;
 }
index 20c30bdac86ec1093abe347fcd8394c417c936ac..078208342f31e1cb922d3d0b2e8d875adaccbe67 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2018 Tobias Brunner
+ * Copyright (C) 2010-2025 Tobias Brunner
  * Copyright (C) 2008 Martin Willi
  *
  * Copyright (C) secunet Security Networks AG
@@ -285,6 +285,24 @@ bool library_init(char *settings, const char *namespace);
  */
 void library_deinit();
 
+/**
+ * Custom function called during init/deinit of a library.
+ *
+ * @param init                 TRUE during init, FALSE during deinit
+ * @return                             FALSE if an error occurred and init should fail
+ */
+typedef bool (*library_init_t)(bool init);
+
+/**
+ * Register a custom init function that's called at the end of library_init()
+ * and the start of library_deinit().
+ *
+ * To be called from __attribute__((constructor)) functions.
+ *
+ * @param init                         init function
+ */
+void library_init_register(library_init_t init);
+
 /**
  * Library instance, set after library_init() and before library_deinit() calls.
  */