8 #include "ecore_file_private.h"
14 * - Implement recursive as an option!
15 * - Keep whole path or just name of file? (Memory or CPU...)
16 * - Remove requests without files?
20 typedef struct _Ecore_File_Monitor_Poll Ecore_File_Monitor_Poll;
22 #define ECORE_FILE_MONITOR_POLL(x) ((Ecore_File_Monitor_Poll *)(x))
24 struct _Ecore_File_Monitor_Poll
26 Ecore_File_Monitor monitor;
28 unsigned char deleted;
31 #define ECORE_FILE_INTERVAL_MIN 1.0
32 #define ECORE_FILE_INTERVAL_STEP 0.5
33 #define ECORE_FILE_INTERVAL_MAX 5.0
35 static double _interval = ECORE_FILE_INTERVAL_MIN;
36 static Ecore_Timer *_timer = NULL;
37 static Ecore_File_Monitor *_monitors = NULL;
40 static Eina_Bool _ecore_file_monitor_poll_handler(void *data);
41 static void _ecore_file_monitor_poll_check(Ecore_File_Monitor *em);
42 static int _ecore_file_monitor_poll_checking(Ecore_File_Monitor *em, char *name);
45 ecore_file_monitor_poll_init(void)
51 ecore_file_monitor_poll_shutdown(void)
54 ecore_file_monitor_poll_del(_monitors);
58 ecore_timer_del(_timer);
65 ecore_file_monitor_poll_add(const char *path,
66 void (*func) (void *data, Ecore_File_Monitor *em,
67 Ecore_File_Event event,
71 Ecore_File_Monitor *em;
74 if (!path) return NULL;
75 if (!func) return NULL;
77 em = calloc(1, sizeof(Ecore_File_Monitor_Poll));
81 _timer = ecore_timer_add(_interval, _ecore_file_monitor_poll_handler, NULL);
83 ecore_timer_interval_set(_timer, ECORE_FILE_INTERVAL_MIN);
85 em->path = strdup(path);
86 len = strlen(em->path);
87 if (em->path[len - 1] == '/' && strcmp(em->path, "/"))
88 em->path[len - 1] = 0;
93 ECORE_FILE_MONITOR_POLL(em)->mtime = ecore_file_mod_time(em->path);
94 _monitors = ECORE_FILE_MONITOR(eina_inlist_append(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em)));
96 if (ecore_file_exists(em->path))
98 if (ecore_file_is_dir(em->path))
100 /* Check for subdirs */
104 files = ecore_file_ls(em->path);
105 EINA_LIST_FREE(files, file)
110 f = calloc(1, sizeof(Ecore_File));
117 snprintf(buf, sizeof(buf), "%s/%s", em->path, file);
119 f->mtime = ecore_file_mod_time(buf);
120 f->is_dir = ecore_file_is_dir(buf);
121 em->files = (Ecore_File *) eina_inlist_append(EINA_INLIST_GET(em->files), EINA_INLIST_GET(f));
127 ecore_file_monitor_poll_del(em);
135 ecore_file_monitor_poll_del(Ecore_File_Monitor *em)
141 ECORE_FILE_MONITOR_POLL(em)->deleted = 1;
146 /*It's possible there weren't any files to monitor, so check if the list is init*/
149 for (l = em->files; l;)
151 Ecore_File *file = l;
153 l = (Ecore_File *) EINA_INLIST_GET(l)->next;
160 _monitors = ECORE_FILE_MONITOR(eina_inlist_remove(EINA_INLIST_GET(_monitors), EINA_INLIST_GET(em)));
169 ecore_timer_del(_timer);
173 ecore_timer_interval_set(_timer, ECORE_FILE_INTERVAL_MIN);
178 _ecore_file_monitor_poll_handler(void *data __UNUSED__)
180 Ecore_File_Monitor *l;
182 _interval += ECORE_FILE_INTERVAL_STEP;
185 EINA_INLIST_FOREACH(_monitors, l)
186 _ecore_file_monitor_poll_check(l);
189 if (_interval > ECORE_FILE_INTERVAL_MAX)
190 _interval = ECORE_FILE_INTERVAL_MAX;
191 ecore_timer_interval_set(_timer, _interval);
193 for (l = _monitors; l;)
195 Ecore_File_Monitor *em = l;
197 l = ECORE_FILE_MONITOR(EINA_INLIST_GET(l)->next);
198 if (ECORE_FILE_MONITOR_POLL(em)->deleted)
199 ecore_file_monitor_del(em);
201 return ECORE_CALLBACK_RENEW;
205 _ecore_file_monitor_poll_check(Ecore_File_Monitor *em)
209 mtime = ecore_file_mod_time(em->path);
210 if (mtime < ECORE_FILE_MONITOR_POLL(em)->mtime)
213 Ecore_File_Event event;
215 /* Notify all files deleted */
216 for (l = em->files; l;)
221 l = (Ecore_File *) EINA_INLIST_GET(l)->next;
223 snprintf(buf, sizeof(buf), "%s/%s", em->path, f->name);
225 event = ECORE_FILE_EVENT_DELETED_DIRECTORY;
227 event = ECORE_FILE_EVENT_DELETED_FILE;
228 em->func(em->data, em, event, buf);
233 em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path);
234 _interval = ECORE_FILE_INTERVAL_MIN;
240 /* Check for changed files */
241 for (l = em->files; l;)
246 Ecore_File_Event event;
248 l = (Ecore_File *) EINA_INLIST_GET(l)->next;
250 snprintf(buf, sizeof(buf), "%s/%s", em->path, f->name);
251 mtime = ecore_file_mod_time(buf);
252 if (mtime < f->mtime)
255 event = ECORE_FILE_EVENT_DELETED_DIRECTORY;
257 event = ECORE_FILE_EVENT_DELETED_FILE;
259 em->func(em->data, em, event, buf);
260 em->files = (Ecore_File *) eina_inlist_remove(EINA_INLIST_GET(em->files), EINA_INLIST_GET(f));
263 _interval = ECORE_FILE_INTERVAL_MIN;
265 else if ((mtime > f->mtime) && !(f->is_dir))
267 em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, buf);
268 _interval = ECORE_FILE_INTERVAL_MIN;
275 /* Check for new files */
276 if (ECORE_FILE_MONITOR_POLL(em)->mtime < mtime)
282 /* Files have been added or removed */
283 files = ecore_file_ls(em->path);
286 /* Are we a directory? We should check first, rather than rely on null here*/
287 EINA_LIST_FOREACH(files, l, file)
291 Ecore_File_Event event;
293 if (_ecore_file_monitor_poll_checking(em, file))
296 snprintf(buf, sizeof(buf), "%s/%s", em->path, file);
297 f = calloc(1, sizeof(Ecore_File));
301 f->name = strdup(file);
302 f->mtime = ecore_file_mod_time(buf);
303 f->is_dir = ecore_file_mod_time(buf);
305 event = ECORE_FILE_EVENT_CREATED_DIRECTORY;
307 event = ECORE_FILE_EVENT_CREATED_FILE;
308 em->func(em->data, em, event, buf);
309 em->files = (Ecore_File *) eina_inlist_append(EINA_INLIST_GET(em->files), EINA_INLIST_GET(f));
313 file = eina_list_data_get(files);
315 files = eina_list_remove_list(files, files);
319 if (!ecore_file_is_dir(em->path))
320 em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, em->path);
321 _interval = ECORE_FILE_INTERVAL_MIN;
324 ECORE_FILE_MONITOR_POLL(em)->mtime = mtime;
328 _ecore_file_monitor_poll_checking(Ecore_File_Monitor *em, char *name)
332 EINA_INLIST_FOREACH(em->files, l)
334 if (!strcmp(l->name, name))