From: Daniel Wagner <daniel.wag...@bmw-carit.de>

---
 include/storage.h |   8 +++
 src/config.c      | 122 +-----------------------------------------
 src/connman.h     |   5 ++
 src/main.c        |   2 +
 src/storage.c     | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 172 insertions(+), 120 deletions(-)

diff --git a/include/storage.h b/include/storage.h
index 4c23a14..4582390 100644
--- a/include/storage.h
+++ b/include/storage.h
@@ -28,9 +28,17 @@
 extern "C" {
 #endif
 
+struct inotify_event;
+
+typedef void (* storage_notify_cb) (struct inotify_event *event,
+                                       const char *ident);
+
 gchar **connman_storage_get_services();
 GKeyFile *connman_storage_load_service(const char *service_id);
 
+int connman_storage_notify_register(storage_notify_cb callback);
+void connman_storage_notify_unregister(storage_notify_cb callback);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/config.c b/src/config.c
index 16fed8d..d70af8f 100644
--- a/src/config.c
+++ b/src/config.c
@@ -66,10 +66,6 @@ struct connman_config {
 static GHashTable *config_table = NULL;
 static GSList *protected_services = NULL;
 
-static int inotify_wd = -1;
-
-static GIOChannel *inotify_channel = NULL;
-static uint inotify_watch = 0;
 static connman_bool_t cleanup = FALSE;
 
 #define INTERNAL_CONFIG_PREFIX           "__internal"
@@ -613,120 +609,6 @@ static void config_notify_handler(struct inotify_event 
*event,
                g_hash_table_remove(config_table, ident);
 }
 
-static gboolean inotify_data(GIOChannel *channel, GIOCondition cond,
-                                                       gpointer user_data)
-{
-       char buffer[256];
-       char *next_event;
-       gsize bytes_read;
-       GIOStatus status;
-
-       if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
-               inotify_watch = 0;
-               return FALSE;
-       }
-
-       status = g_io_channel_read_chars(channel, buffer,
-                                       sizeof(buffer) -1, &bytes_read, NULL);
-
-       switch (status) {
-       case G_IO_STATUS_NORMAL:
-               break;
-       case G_IO_STATUS_AGAIN:
-               return TRUE;
-       default:
-               connman_error("Reading from inotify channel failed");
-               inotify_watch = 0;
-               return FALSE;
-       }
-
-       next_event = buffer;
-
-       while (bytes_read > 0) {
-               struct inotify_event *event;
-               gchar *ident;
-               gsize len;
-
-               event = (struct inotify_event *) next_event;
-               if (event->len)
-                       ident = next_event + sizeof(struct inotify_event);
-               else
-                       ident = NULL;
-
-               len = sizeof(struct inotify_event) + event->len;
-
-               /* check if inotify_event block fit */
-               if (len > bytes_read)
-                       break;
-
-               next_event += len;
-               bytes_read -= len;
-
-               config_notify_handler(event, ident);
-       }
-
-       return TRUE;
-}
-
-static int create_watch(void)
-{
-       int fd;
-
-       fd = inotify_init();
-       if (fd < 0)
-               return -EIO;
-
-       inotify_wd = inotify_add_watch(fd, STORAGEDIR,
-                                       IN_MODIFY | IN_CREATE | IN_DELETE);
-       if (inotify_wd < 0) {
-               connman_error("Creation of STORAGEDIR  watch failed");
-               close(fd);
-               return -EIO;
-       }
-
-       inotify_channel = g_io_channel_unix_new(fd);
-       if (inotify_channel == NULL) {
-               connman_error("Creation of inotify channel failed");
-               inotify_rm_watch(fd, inotify_wd);
-               inotify_wd = 0;
-
-               close(fd);
-               return -EIO;
-       }
-
-       g_io_channel_set_close_on_unref(inotify_channel, TRUE);
-       g_io_channel_set_encoding(inotify_channel, NULL, NULL);
-       g_io_channel_set_buffered(inotify_channel, FALSE);
-
-       inotify_watch = g_io_add_watch(inotify_channel,
-                               G_IO_IN | G_IO_HUP | G_IO_NVAL | G_IO_ERR,
-                               inotify_data, NULL);
-
-       return 0;
-}
-
-static void remove_watch(void)
-{
-       int fd;
-
-       if (inotify_channel == NULL)
-               return;
-
-       if (inotify_watch > 0) {
-               g_source_remove(inotify_watch);
-               inotify_watch = 0;
-       }
-
-       fd = g_io_channel_unix_get_fd(inotify_channel);
-
-       if (inotify_wd >= 0) {
-               inotify_rm_watch(fd, inotify_wd);
-               inotify_wd = 0;
-       }
-
-       g_io_channel_unref(inotify_channel);
-}
-
 int __connman_config_init(void)
 {
        DBG("");
@@ -734,7 +616,7 @@ int __connman_config_init(void)
        config_table = g_hash_table_new_full(g_str_hash, g_str_equal,
                                                NULL, unregister_config);
 
-       create_watch();
+       connman_storage_notify_register(config_notify_handler);
 
        return read_configs();
 }
@@ -745,7 +627,7 @@ void __connman_config_cleanup(void)
 
        cleanup = TRUE;
 
-       remove_watch();
+       connman_storage_notify_unregister(config_notify_handler);
 
        g_hash_table_destroy(config_table);
        config_table = NULL;
diff --git a/src/connman.h b/src/connman.h
index 764422c..7ccea97 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -208,6 +208,8 @@ int __connman_resolvfile_append(const char *interface, 
const char *domain, const
 int __connman_resolvfile_remove(const char *interface, const char *domain, 
const char *server);
 int __connman_resolver_redo_servers(const char *interface);
 
+#include <connman/storage.h>
+
 void __connman_storage_migrate(void);
 GKeyFile *__connman_storage_open_global(void);
 GKeyFile *__connman_storage_load_global(void);
@@ -223,6 +225,9 @@ void __connman_storage_save_provider(GKeyFile *keyfile, 
const char *identifier);
 char **__connman_storage_get_providers(void);
 gboolean __connman_storage_remove_service(const char *service_id);
 
+int __connman_storage_init(void);
+void __connman_storage_cleanup(void);
+
 int __connman_detect_init(void);
 void __connman_detect_cleanup(void);
 
diff --git a/src/main.c b/src/main.c
index d14cee6..225afd5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -545,6 +545,7 @@ int main(int argc, char *argv[])
                config_init(option_config);
 
        __connman_storage_migrate();
+       __connman_storage_init();
        __connman_technology_init();
        __connman_notifier_init();
        __connman_service_init();
@@ -624,6 +625,7 @@ int main(int argc, char *argv[])
        __connman_ipconfig_cleanup();
        __connman_notifier_cleanup();
        __connman_technology_cleanup();
+       __connman_storage_cleanup();
 
        __connman_dbus_cleanup();
 
diff --git a/src/storage.c b/src/storage.c
index 8c06ffe..9c86575 100644
--- a/src/storage.c
+++ b/src/storage.c
@@ -27,6 +27,7 @@
 #include <unistd.h>
 #include <sys/stat.h>
 #include <dirent.h>
+#include <sys/inotify.h>
 
 #include <connman/storage.h>
 
@@ -38,6 +39,13 @@
 #define MODE           (S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | \
                        S_IXGRP | S_IROTH | S_IXOTH)
 
+static int inotify_wd = -1;
+
+static GIOChannel *inotify_channel = NULL;
+static uint inotify_watch = 0;
+
+static GSList *notify_list;
+
 static GKeyFile *storage_load(const char *pathname)
 {
        GKeyFile *keyfile = NULL;
@@ -610,3 +618,150 @@ void __connman_storage_migrate(void)
 done:
        g_free(pathname);
 }
+
+static gboolean inotify_data(GIOChannel *channel, GIOCondition cond,
+                                                       gpointer user_data)
+{
+       char buffer[256];
+       char *next_event;
+       gsize bytes_read;
+       GIOStatus status;
+       GSList *list;
+
+       if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+               inotify_watch = 0;
+               return FALSE;
+       }
+
+       status = g_io_channel_read_chars(channel, buffer,
+                                       sizeof(buffer) -1, &bytes_read, NULL);
+
+       switch (status) {
+       case G_IO_STATUS_NORMAL:
+               break;
+       case G_IO_STATUS_AGAIN:
+               return TRUE;
+       default:
+               connman_error("Reading from inotify channel failed");
+               inotify_watch = 0;
+               return FALSE;
+       }
+
+       next_event = buffer;
+
+       while (bytes_read > 0) {
+               struct inotify_event *event;
+               gchar *ident;
+               gsize len;
+
+               event = (struct inotify_event *) next_event;
+               if (event->len)
+                       ident = next_event + sizeof(struct inotify_event);
+               else
+                       ident = NULL;
+
+               len = sizeof(struct inotify_event) + event->len;
+
+               /* check if inotify_event block fit */
+               if (len > bytes_read)
+                       break;
+
+               next_event += len;
+               bytes_read -= len;
+
+
+               for (list = notify_list; list != NULL; list = list->next) {
+                       storage_notify_cb callback = list->data;
+
+                       (*callback)(event, ident);
+               }
+       }
+
+       return TRUE;
+}
+
+static int create_watch(void)
+{
+       int fd;
+
+       fd = inotify_init();
+       if (fd < 0)
+               return -EIO;
+
+       inotify_wd = inotify_add_watch(fd, STORAGEDIR,
+                                       IN_MODIFY | IN_CREATE | IN_DELETE);
+       if (inotify_wd < 0) {
+               connman_error("Creation of STORAGEDIR  watch failed");
+               close(fd);
+               return -EIO;
+       }
+
+       inotify_channel = g_io_channel_unix_new(fd);
+       if (inotify_channel == NULL) {
+               connman_error("Creation of inotify channel failed");
+               inotify_rm_watch(fd, inotify_wd);
+               inotify_wd = 0;
+
+               close(fd);
+               return -EIO;
+       }
+
+       g_io_channel_set_close_on_unref(inotify_channel, TRUE);
+       g_io_channel_set_encoding(inotify_channel, NULL, NULL);
+       g_io_channel_set_buffered(inotify_channel, FALSE);
+
+       inotify_watch = g_io_add_watch(inotify_channel,
+                               G_IO_IN | G_IO_HUP | G_IO_NVAL | G_IO_ERR,
+                               inotify_data, NULL);
+
+       return 0;
+}
+
+static void remove_watch(void)
+{
+       int fd;
+
+       if (inotify_channel == NULL)
+               return;
+
+       if (inotify_watch > 0) {
+               g_source_remove(inotify_watch);
+               inotify_watch = 0;
+       }
+
+       fd = g_io_channel_unix_get_fd(inotify_channel);
+
+       if (inotify_wd >= 0) {
+               inotify_rm_watch(fd, inotify_wd);
+               inotify_wd = 0;
+       }
+
+       g_io_channel_unref(inotify_channel);
+}
+
+int connman_storage_notify_register(storage_notify_cb callback)
+{
+       notify_list = g_slist_prepend(notify_list, callback);
+
+       return 0;
+}
+
+void connman_storage_notify_unregister(storage_notify_cb callback)
+{
+       notify_list = g_slist_remove(notify_list, callback);
+}
+
+int __connman_storage_init(void)
+{
+       create_watch();
+
+       return 0;
+}
+
+void __connman_storage_cleanup(void)
+{
+       remove_watch();
+
+       g_slist_free(notify_list);
+       notify_list = NULL;
+}
-- 
1.7.11.4

_______________________________________________
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman

Reply via email to