2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
12 #include "ecore_file_private.h"
18 * - Implement recursive as an option!
19 * - Keep whole path or just name of file? (Memory or CPU...)
20 * - Remove requests without files?
24 typedef struct _Ecore_File_Monitor_Poll Ecore_File_Monitor_Poll;
26 #define ECORE_FILE_MONITOR_POLL(x) ((Ecore_File_Monitor_Poll *)(x))
28 struct _Ecore_File_Monitor_Poll
30 Ecore_File_Monitor monitor;
32 unsigned char deleted;
35 #define ECORE_FILE_INTERVAL_MIN 1.0
36 #define ECORE_FILE_INTERVAL_STEP 0.5
37 #define ECORE_FILE_INTERVAL_MAX 5.0
39 static double _interval = ECORE_FILE_INTERVAL_MIN;
40 static Ecore_Timer *_timer = NULL;
41 static Ecore_File_Monitor *_monitors = NULL;
44 static int _ecore_file_monitor_poll_handler(void *data);
45 static void _ecore_file_monitor_poll_check(Ecore_File_Monitor *em);
46 static int _ecore_file_monitor_poll_checking(Ecore_File_Monitor *em, char *name);
49 ecore_file_monitor_poll_init(void)
55 ecore_file_monitor_poll_shutdown(void)
58 ecore_file_monitor_poll_del(_monitors);
62 ecore_timer_del(_timer);
69 ecore_file_monitor_poll_add(const char *path,
70 void (*func) (void *data, Ecore_File_Monitor *em,
71 Ecore_File_Event event,
75 Ecore_File_Monitor *em;
78 if (!path) return NULL;
79 if (!func) return NULL;
81 em = calloc(1, sizeof(Ecore_File_Monitor_Poll));
85 _timer = ecore_timer_add(_interval, _ecore_file_monitor_poll_handler, NULL);
87 ecore_timer_interval_set(_timer, ECORE_FILE_INTERVAL_MIN);
89 em->path = strdup(path);
90 len = strlen(em->path);
91 if (em->path[len - 1] == '/' && strcmp(em->path, "/"))
92 em->path[len - 1] = 0;
97 ECORE_FILE_MONITOR_POLL(em)->mtime = ecore_file_mod_time(em->path);
98 if (ecore_file_exists(em->path))
100 if (ecore_file_is_dir(em->path))
102 /* Check for subdirs */
106 files = ecore_file_ls(em->path);
107 EINA_LIST_FREE(files, file)
112 f = calloc(1, sizeof(Ecore_File));
119 snprintf(buf, sizeof(buf), "%s/%s", em->path, file);
121 f->mtime = ecore_file_mod_time(buf);
122 f->is_dir = ecore_file_is_dir(buf);
123 em->files = (Ecore_File *) eina_inlist_append(EINA_INLIST_GET(em->files), EINA_INLIST_GET(f));
129 ecore_file_monitor_poll_del(em);
133 _monitors = ECORE_FILE_MONITOR(eina_inlist_append(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em)));
139 ecore_file_monitor_poll_del(Ecore_File_Monitor *em)
145 ECORE_FILE_MONITOR_POLL(em)->deleted = 1;
150 /*It's possible there weren't any files to monitor, so check if the list is init*/
153 for (l = em->files; l;)
155 Ecore_File *file = l;
157 l = (Ecore_File *) EINA_INLIST_GET(l)->next;
164 _monitors = ECORE_FILE_MONITOR(eina_inlist_remove(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em)));
173 ecore_timer_del(_timer);
177 ecore_timer_interval_set(_timer, ECORE_FILE_INTERVAL_MIN);
182 _ecore_file_monitor_poll_handler(void *data __UNUSED__)
184 Ecore_File_Monitor *l;
186 _interval += ECORE_FILE_INTERVAL_STEP;
189 EINA_INLIST_FOREACH(_monitors, l)
190 _ecore_file_monitor_poll_check(l);
193 if (_interval > ECORE_FILE_INTERVAL_MAX)
194 _interval = ECORE_FILE_INTERVAL_MAX;
195 ecore_timer_interval_set(_timer, _interval);
197 for (l = _monitors; l;)
199 Ecore_File_Monitor *em = l;
201 l = ECORE_FILE_MONITOR(EINA_INLIST_GET(l)->next);
202 if (ECORE_FILE_MONITOR_POLL(em)->deleted)
203 ecore_file_monitor_del(em);
209 _ecore_file_monitor_poll_check(Ecore_File_Monitor *em)
213 mtime = ecore_file_mod_time(em->path);
214 if (mtime < ECORE_FILE_MONITOR_POLL(em)->mtime)
217 Ecore_File_Event event;
219 /* Notify all files deleted */
220 for (l = em->files; l;)
225 l = (Ecore_File *) EINA_INLIST_GET(l)->next;
227 snprintf(buf, sizeof(buf), "%s/%s", em->path, f->name);
229 event = ECORE_FILE_EVENT_DELETED_DIRECTORY;
231 event = ECORE_FILE_EVENT_DELETED_FILE;
232 em->func(em->data, em, event, buf);
237 em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path);
238 _interval = ECORE_FILE_INTERVAL_MIN;
244 /* Check for changed files */
245 for (l = em->files; l;)
250 Ecore_File_Event event;
252 l = (Ecore_File *) EINA_INLIST_GET(l)->next;
254 snprintf(buf, sizeof(buf), "%s/%s", em->path, f->name);
255 mtime = ecore_file_mod_time(buf);
256 if (mtime < f->mtime)
259 event = ECORE_FILE_EVENT_DELETED_DIRECTORY;
261 event = ECORE_FILE_EVENT_DELETED_FILE;
263 em->func(em->data, em, event, buf);
264 em->files = (Ecore_File *) eina_inlist_remove(EINA_INLIST_GET(em->files), EINA_INLIST_GET(f));
267 _interval = ECORE_FILE_INTERVAL_MIN;
269 else if ((mtime > f->mtime) && !(f->is_dir))
271 em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, buf);
272 _interval = ECORE_FILE_INTERVAL_MIN;
279 /* Check for new files */
280 if (ECORE_FILE_MONITOR_POLL(em)->mtime < mtime)
286 /* Files have been added or removed */
287 files = ecore_file_ls(em->path);
290 /* Are we a directory? We should check first, rather than rely on null here*/
291 EINA_LIST_FOREACH(files, l, file)
295 Ecore_File_Event event;
297 if (_ecore_file_monitor_poll_checking(em, file))
300 snprintf(buf, sizeof(buf), "%s/%s", em->path, file);
301 f = calloc(1, sizeof(Ecore_File));
305 f->name = strdup(file);
306 f->mtime = ecore_file_mod_time(buf);
307 f->is_dir = ecore_file_mod_time(buf);
309 event = ECORE_FILE_EVENT_CREATED_DIRECTORY;
311 event = ECORE_FILE_EVENT_CREATED_FILE;
312 em->func(em->data, em, event, buf);
313 em->files = (Ecore_File *) eina_inlist_append(EINA_INLIST_GET(em->files), EINA_INLIST_GET(f));
317 file = eina_list_data_get(files);
319 files = eina_list_remove_list(files, files);
323 if (!ecore_file_is_dir(em->path))
324 em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, em->path);
325 _interval = ECORE_FILE_INTERVAL_MIN;
328 ECORE_FILE_MONITOR_POLL(em)->mtime = mtime;
332 _ecore_file_monitor_poll_checking(Ecore_File_Monitor *em, char *name)
336 EINA_INLIST_FOREACH(em->files, l)
338 if (!strcmp(l->name, name))