diff options
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.c | 340 |
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 | |||
21 | typedef struct _Ecore_File_Monitor_Poll Ecore_File_Monitor_Poll; | ||
22 | |||
23 | #define ECORE_FILE_MONITOR_POLL(x) ((Ecore_File_Monitor_Poll *)(x)) | ||
24 | |||
25 | struct _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 | |||
36 | static double _interval = ECORE_FILE_INTERVAL_MIN; | ||
37 | static Ecore_Timer *_timer = NULL; | ||
38 | static Ecore_File_Monitor *_monitors = NULL; | ||
39 | static int _lock = 0; | ||
40 | |||
41 | static Eina_Bool _ecore_file_monitor_poll_handler(void *data); | ||
42 | static void _ecore_file_monitor_poll_check(Ecore_File_Monitor *em); | ||
43 | static int _ecore_file_monitor_poll_checking(Ecore_File_Monitor *em, char *name); | ||
44 | |||
45 | int | ||
46 | ecore_file_monitor_poll_init(void) | ||
47 | { | ||
48 | return 1; | ||
49 | } | ||
50 | |||
51 | int | ||
52 | ecore_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 | |||
65 | Ecore_File_Monitor * | ||
66 | ecore_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 | |||
135 | void | ||
136 | ecore_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 | |||
178 | static 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 | |||
205 | static 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 | |||
328 | static 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 | ||