aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c')
-rw-r--r--libraries/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c340
1 files changed, 0 insertions, 340 deletions
diff --git a/libraries/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c b/libraries/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c
deleted file mode 100644
index 49bfcb6..0000000
--- a/libraries/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c
+++ /dev/null
@@ -1,340 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <stdlib.h>
6#include <stdio.h>
7#include <string.h>
8
9#include "ecore_file_private.h"
10
11#ifdef HAVE_POLL
12
13/*
14 * TODO:
15 * - Implement recursive as an option!
16 * - Keep whole path or just name of file? (Memory or CPU...)
17 * - Remove requests without files?
18 * - Change poll time
19 */
20
21typedef struct _Ecore_File_Monitor_Poll Ecore_File_Monitor_Poll;
22
23#define ECORE_FILE_MONITOR_POLL(x) ((Ecore_File_Monitor_Poll *)(x))
24
25struct _Ecore_File_Monitor_Poll
26{
27 Ecore_File_Monitor monitor;
28 int mtime;
29 unsigned char deleted;
30};
31
32#define ECORE_FILE_INTERVAL_MIN 1.0
33#define ECORE_FILE_INTERVAL_STEP 0.5
34#define ECORE_FILE_INTERVAL_MAX 5.0
35
36static double _interval = ECORE_FILE_INTERVAL_MIN;
37static Ecore_Timer *_timer = NULL;
38static Ecore_File_Monitor *_monitors = NULL;
39static int _lock = 0;
40
41static Eina_Bool _ecore_file_monitor_poll_handler(void *data);
42static void _ecore_file_monitor_poll_check(Ecore_File_Monitor *em);
43static int _ecore_file_monitor_poll_checking(Ecore_File_Monitor *em, char *name);
44
45int
46ecore_file_monitor_poll_init(void)
47{
48 return 1;
49}
50
51int
52ecore_file_monitor_poll_shutdown(void)
53{
54 while(_monitors)
55 ecore_file_monitor_poll_del(_monitors);
56
57 if (_timer)
58 {
59 ecore_timer_del(_timer);
60 _timer = NULL;
61 }
62 return 1;
63}
64
65Ecore_File_Monitor *
66ecore_file_monitor_poll_add(const char *path,
67 void (*func) (void *data, Ecore_File_Monitor *em,
68 Ecore_File_Event event,
69 const char *path),
70 void *data)
71{
72 Ecore_File_Monitor *em;
73 size_t len;
74
75 if (!path) return NULL;
76 if (!func) return NULL;
77
78 em = calloc(1, sizeof(Ecore_File_Monitor_Poll));
79 if (!em) return NULL;
80
81 if (!_timer)
82 _timer = ecore_timer_add(_interval, _ecore_file_monitor_poll_handler, NULL);
83 else
84 ecore_timer_interval_set(_timer, ECORE_FILE_INTERVAL_MIN);
85
86 em->path = strdup(path);
87 len = strlen(em->path);
88 if (em->path[len - 1] == '/' && strcmp(em->path, "/"))
89 em->path[len - 1] = 0;
90
91 em->func = func;
92 em->data = data;
93
94 ECORE_FILE_MONITOR_POLL(em)->mtime = ecore_file_mod_time(em->path);
95 _monitors = ECORE_FILE_MONITOR(eina_inlist_append(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em)));
96
97 if (ecore_file_exists(em->path))
98 {
99 if (ecore_file_is_dir(em->path))
100 {
101 /* Check for subdirs */
102 Eina_List *files;
103 char *file;
104
105 files = ecore_file_ls(em->path);
106 EINA_LIST_FREE(files, file)
107 {
108 Ecore_File *f;
109 char buf[PATH_MAX];
110
111 f = calloc(1, sizeof(Ecore_File));
112 if (!f)
113 {
114 free(file);
115 continue;
116 }
117
118 snprintf(buf, sizeof(buf), "%s/%s", em->path, file);
119 f->name = file;
120 f->mtime = ecore_file_mod_time(buf);
121 f->is_dir = ecore_file_is_dir(buf);
122 em->files = (Ecore_File *) eina_inlist_append(EINA_INLIST_GET(em->files), EINA_INLIST_GET(f));
123 }
124 }
125 }
126 else
127 {
128 ecore_file_monitor_poll_del(em);
129 return NULL;
130 }
131
132 return em;
133}
134
135void
136ecore_file_monitor_poll_del(Ecore_File_Monitor *em)
137{
138 Ecore_File *l;
139
140 if (_lock)
141 {
142 ECORE_FILE_MONITOR_POLL(em)->deleted = 1;
143 return;
144 }
145
146 /* Remove files */
147 /*It's possible there weren't any files to monitor, so check if the list is init*/
148 if (em->files)
149 {
150 for (l = em->files; l;)
151 {
152 Ecore_File *file = l;
153
154 l = (Ecore_File *) EINA_INLIST_GET(l)->next;
155 free(file->name);
156 free(file);
157 }
158 }
159
160 if (_monitors)
161 _monitors = ECORE_FILE_MONITOR(eina_inlist_remove(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em)));
162
163 free(em->path);
164 free(em);
165
166 if (_timer)
167 {
168 if (!_monitors)
169 {
170 ecore_timer_del(_timer);
171 _timer = NULL;
172 }
173 else
174 ecore_timer_interval_set(_timer, ECORE_FILE_INTERVAL_MIN);
175 }
176}
177
178static Eina_Bool
179_ecore_file_monitor_poll_handler(void *data __UNUSED__)
180{
181 Ecore_File_Monitor *l;
182
183 _interval += ECORE_FILE_INTERVAL_STEP;
184
185 _lock = 1;
186 EINA_INLIST_FOREACH(_monitors, l)
187 _ecore_file_monitor_poll_check(l);
188 _lock = 0;
189
190 if (_interval > ECORE_FILE_INTERVAL_MAX)
191 _interval = ECORE_FILE_INTERVAL_MAX;
192 ecore_timer_interval_set(_timer, _interval);
193
194 for (l = _monitors; l;)
195 {
196 Ecore_File_Monitor *em = l;
197
198 l = ECORE_FILE_MONITOR(EINA_INLIST_GET(l)->next);
199 if (ECORE_FILE_MONITOR_POLL(em)->deleted)
200 ecore_file_monitor_del(em);
201 }
202 return ECORE_CALLBACK_RENEW;
203}
204
205static void
206_ecore_file_monitor_poll_check(Ecore_File_Monitor *em)
207{
208 int mtime;
209
210 mtime = ecore_file_mod_time(em->path);
211 if (mtime < ECORE_FILE_MONITOR_POLL(em)->mtime)
212 {
213 Ecore_File *l;
214 Ecore_File_Event event;
215
216 /* Notify all files deleted */
217 for (l = em->files; l;)
218 {
219 Ecore_File *f = l;
220 char buf[PATH_MAX];
221
222 l = (Ecore_File *) EINA_INLIST_GET(l)->next;
223
224 snprintf(buf, sizeof(buf), "%s/%s", em->path, f->name);
225 if (f->is_dir)
226 event = ECORE_FILE_EVENT_DELETED_DIRECTORY;
227 else
228 event = ECORE_FILE_EVENT_DELETED_FILE;
229 em->func(em->data, em, event, buf);
230 free(f->name);
231 free(f);
232 }
233 em->files = NULL;
234 em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path);
235 _interval = ECORE_FILE_INTERVAL_MIN;
236 }
237 else
238 {
239 Ecore_File *l;
240
241 /* Check for changed files */
242 for (l = em->files; l;)
243 {
244 Ecore_File *f = l;
245 char buf[PATH_MAX];
246 int mt;
247 Ecore_File_Event event;
248
249 l = (Ecore_File *) EINA_INLIST_GET(l)->next;
250
251 snprintf(buf, sizeof(buf), "%s/%s", em->path, f->name);
252 mt = ecore_file_mod_time(buf);
253 if (mt < f->mtime)
254 {
255 if (f->is_dir)
256 event = ECORE_FILE_EVENT_DELETED_DIRECTORY;
257 else
258 event = ECORE_FILE_EVENT_DELETED_FILE;
259
260 em->func(em->data, em, event, buf);
261 em->files = (Ecore_File *) eina_inlist_remove(EINA_INLIST_GET(em->files), EINA_INLIST_GET(f));
262 free(f->name);
263 free(f);
264 _interval = ECORE_FILE_INTERVAL_MIN;
265 }
266 else if ((mt > f->mtime) && !(f->is_dir))
267 {
268 em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, buf);
269 _interval = ECORE_FILE_INTERVAL_MIN;
270 f->mtime = mt;
271 }
272 else
273 f->mtime = mt;
274 }
275
276 /* Check for new files */
277 if (ECORE_FILE_MONITOR_POLL(em)->mtime < mtime)
278 {
279 Eina_List *files;
280 Eina_List *fl;
281 char *file;
282
283 /* Files have been added or removed */
284 files = ecore_file_ls(em->path);
285 if (files)
286 {
287 /* Are we a directory? We should check first, rather than rely on null here*/
288 EINA_LIST_FOREACH(files, fl, file)
289 {
290 Ecore_File *f;
291 char buf[PATH_MAX];
292 Ecore_File_Event event;
293
294 if (_ecore_file_monitor_poll_checking(em, file))
295 continue;
296
297 snprintf(buf, sizeof(buf), "%s/%s", em->path, file);
298 f = calloc(1, sizeof(Ecore_File));
299 if (!f)
300 continue;
301
302 f->name = strdup(file);
303 f->mtime = ecore_file_mod_time(buf);
304 f->is_dir = ecore_file_is_dir(buf);
305 if (f->is_dir)
306 event = ECORE_FILE_EVENT_CREATED_DIRECTORY;
307 else
308 event = ECORE_FILE_EVENT_CREATED_FILE;
309 em->func(em->data, em, event, buf);
310 em->files = (Ecore_File *) eina_inlist_append(EINA_INLIST_GET(em->files), EINA_INLIST_GET(f));
311 }
312 while (files)
313 {
314 file = eina_list_data_get(files);
315 free(file);
316 files = eina_list_remove_list(files, files);
317 }
318 }
319
320 if (!ecore_file_is_dir(em->path))
321 em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, em->path);
322 _interval = ECORE_FILE_INTERVAL_MIN;
323 }
324 }
325 ECORE_FILE_MONITOR_POLL(em)->mtime = mtime;
326}
327
328static int
329_ecore_file_monitor_poll_checking(Ecore_File_Monitor *em, char *name)
330{
331 Ecore_File *l;
332
333 EINA_INLIST_FOREACH(em->files, l)
334 {
335 if (!strcmp(l->name, name))
336 return 1;
337 }
338 return 0;
339}
340#endif