2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "helper-inotify.h"
20 #include "stc-manager-util.h"
30 static GHashTable *g_inotify_hash;
32 static void __inotify_destroy(gpointer user_data)
35 stc_inotify_s *inotify = user_data;
37 if (!inotify->channel)
40 if (inotify->watch > 0)
41 g_source_remove(inotify->watch);
43 if (inotify->wd >= 0) {
44 fd = g_io_channel_unix_get_fd(inotify->channel);
45 inotify_rm_watch(fd, inotify->wd);
48 g_io_channel_unref(inotify->channel);
51 static gboolean __inotify_data(GIOChannel *channel,
52 GIOCondition cond, gpointer user_data)
54 stc_inotify_s *inotify = user_data;
56 char *next_event = buf;
60 if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
65 status = g_io_channel_read_chars(channel, buf,
66 sizeof(buf), &bytes_read, NULL);
67 if (status != G_IO_STATUS_NORMAL) {
68 if (status == G_IO_STATUS_AGAIN)
71 STC_LOGE("Failed to read from inotify channel");
77 while (bytes_read > 0) {
78 struct inotify_event *event =
79 (struct inotify_event *)next_event;
83 len = sizeof(*event) + event->len;
88 ident = next_event + sizeof(*event);
93 (inotify->cb)(event, ident);
99 int inotify_register(const char *path, inotify_event_cb cb)
102 stc_inotify_s *inotify;
107 inotify = g_hash_table_lookup(g_inotify_hash, path);
113 inotify = g_try_new0(stc_inotify_s, 1);
123 inotify->wd = inotify_add_watch(fd, path, IN_MODIFY);
124 if (inotify->wd < 0) {
125 STC_LOGE("Failed to create watch [%s]", path);
131 inotify->channel = g_io_channel_unix_new(fd);
132 if (!inotify->channel) {
133 STC_LOGE("Failed to create channel");
134 inotify_rm_watch(fd, inotify->wd);
140 g_io_channel_set_close_on_unref(inotify->channel, TRUE);
141 g_io_channel_set_encoding(inotify->channel, NULL, NULL);
142 g_io_channel_set_buffered(inotify->channel, FALSE);
144 inotify->watch = g_io_add_watch(inotify->channel,
145 G_IO_IN | G_IO_HUP | G_IO_NVAL | G_IO_ERR,
146 __inotify_data, inotify);
150 g_hash_table_insert(g_inotify_hash, g_strdup(path), inotify);
154 void inotify_deregister(const char *path)
156 stc_inotify_s *inotify;
158 inotify = g_hash_table_lookup(g_inotify_hash, path);
162 g_hash_table_remove(g_inotify_hash, path);
165 int inotify_initialize(void)
167 g_inotify_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
168 g_free, __inotify_destroy);
173 void inotify_deinitialize(void)
175 g_hash_table_destroy(g_inotify_hash);