From: Daniel Wagner <[email protected]>
---
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 d035336..c95c5dd 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 62e5c54..35db517 100644
--- a/src/main.c
+++ b/src/main.c
@@ -540,6 +540,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();
@@ -619,6 +620,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.12.1.382.gb0576a6
_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman