libhydra can be initialized more than once
authorMartin Willi <martin@revosec.ch>
Thu, 25 Oct 2012 12:44:06 +0000 (14:44 +0200)
committerMartin Willi <martin@revosec.ch>
Wed, 14 Nov 2012 09:14:34 +0000 (10:14 +0100)
src/libhydra/hydra.c
src/libhydra/hydra.h

index 16fb3ab..b199b2f 100644 (file)
@@ -28,12 +28,22 @@ struct private_hydra_t {
         * Public members of hydra_t.
         */
        hydra_t public;
+
+       /**
+        * Integrity check failed?
+        */
+       bool integrity_failed;
+
+       /**
+        * Number of times we have been initialized
+        */
+       refcount_t ref;
 };
 
 /**
  * Single instance of hydra_t.
  */
-hydra_t *hydra;
+hydra_t *hydra = NULL;
 
 /**
  * Described in header.
@@ -41,6 +51,12 @@ hydra_t *hydra;
 void libhydra_deinit()
 {
        private_hydra_t *this = (private_hydra_t*)hydra;
+
+       if (!this || !ref_put(&this->ref))
+       {       /* have more users */
+               return;
+       }
+
        this->public.attributes->destroy(this->public.attributes);
        this->public.kernel_interface->destroy(this->public.kernel_interface);
        free((void*)this->public.daemon);
@@ -55,11 +71,19 @@ bool libhydra_init(const char *daemon)
 {
        private_hydra_t *this;
 
+       if (hydra)
+       {       /* already initialized, increase refcount */
+               this = (private_hydra_t*)hydra;
+               ref_get(&this->ref);
+               return !this->integrity_failed;
+       }
+
        INIT(this,
                .public = {
                        .attributes = attribute_manager_create(),
                        .daemon = strdup(daemon ?: "libhydra"),
                },
+               .ref = 1,
        );
        hydra = &this->public;
 
@@ -69,8 +93,8 @@ bool libhydra_init(const char *daemon)
                !lib->integrity->check(lib->integrity, "libhydra", libhydra_init))
        {
                DBG1(DBG_LIB, "integrity check of libhydra failed");
-               return FALSE;
+               this->integrity_failed = TRUE;
        }
-       return TRUE;
+       return !this->integrity_failed;
 }
 
index d7a7d8d..2a8709d 100644 (file)
@@ -72,6 +72,9 @@ extern hydra_t *hydra;
  *
  * The daemon's name is used to load daemon-specific settings.
  *
+ * libhydra_init() may be called multiple times in a single process, but each
+ * caller should call libhydra_deinit() for each call to libhydra_init().
+ *
  * @param daemon               name of the daemon that initializes the library
  * @return                             FALSE if integrity check failed
  */