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 = next_event;
82 len = sizeof(*event) + event->len;
87 ident = next_event + sizeof(*event);
92 (inotify->cb)(event, ident);
98 int inotify_register(const char *path, inotify_event_cb cb)
101 stc_inotify_s *inotify;
106 inotify = g_hash_table_lookup(g_inotify_hash, path);
112 inotify = g_try_new0(stc_inotify_s, 1);
122 inotify->wd = inotify_add_watch(fd, path, IN_MODIFY);
123 if (inotify->wd < 0) {
124 STC_LOGE("Failed to create watch [%s]", path);
130 inotify->channel = g_io_channel_unix_new(fd);
131 if (!inotify->channel) {
132 STC_LOGE("Failed to create channel");
133 inotify_rm_watch(fd, inotify->wd);
139 g_io_channel_set_close_on_unref(inotify->channel, TRUE);
140 g_io_channel_set_encoding(inotify->channel, NULL, NULL);
141 g_io_channel_set_buffered(inotify->channel, FALSE);
143 inotify->watch = g_io_add_watch(inotify->channel,
144 G_IO_IN | G_IO_HUP | G_IO_NVAL | G_IO_ERR,
145 __inotify_data, inotify);
149 g_hash_table_insert(g_inotify_hash, g_strdup(path), inotify);
153 void inotify_deregister(const char *path)
155 stc_inotify_s *inotify;
157 inotify = g_hash_table_lookup(g_inotify_hash, path);
161 g_hash_table_remove(g_inotify_hash, path);
164 int inotify_initialize(void)
166 g_inotify_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
167 g_free, __inotify_destroy);
172 void inotify_deinitialize(void)
174 g_hash_table_destroy(g_inotify_hash);