2005-02-20 04:17:07 -08:00
|
|
|
/*
|
|
|
|
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
|
|
|
*/
|
2005-03-01 23:06:44 -08:00
|
|
|
#include "ecore_private.h"
|
2005-02-20 04:17:07 -08:00
|
|
|
#include "ecore_file_private.h"
|
|
|
|
|
|
|
|
#ifdef HAVE_POLL
|
|
|
|
|
|
|
|
/*
|
|
|
|
* TODO:
|
|
|
|
* - Implement recursive as an option!
|
|
|
|
* - Keep whole path or just name of file? (Memory or CPU...)
|
|
|
|
* - Remove requests without files?
|
2005-02-21 08:03:08 -08:00
|
|
|
* - Change poll time
|
2005-02-20 04:17:07 -08:00
|
|
|
*/
|
|
|
|
|
2005-03-29 22:35:12 -08:00
|
|
|
typedef struct _Ecore_File_Monitor_Poll Ecore_File_Monitor_Poll;
|
|
|
|
typedef struct _Ecore_File Ecore_File;
|
|
|
|
|
|
|
|
#define ECORE_FILE_MONITOR_POLL(x) ((Ecore_File_Monitor_Poll *)(x))
|
|
|
|
|
|
|
|
struct _Ecore_File_Monitor_Poll
|
|
|
|
{
|
|
|
|
Ecore_File_Monitor monitor;
|
|
|
|
int mtime;
|
|
|
|
unsigned char deleted;
|
|
|
|
};
|
2005-02-20 04:17:07 -08:00
|
|
|
|
|
|
|
struct _Ecore_File
|
|
|
|
{
|
2005-03-29 22:35:12 -08:00
|
|
|
char *name;
|
|
|
|
int mtime;
|
|
|
|
unsigned char is_dir;
|
2005-02-20 04:17:07 -08:00
|
|
|
};
|
|
|
|
|
2005-02-22 04:38:17 -08:00
|
|
|
#define ECORE_FILE_INTERVAL_MIN 1.0
|
|
|
|
#define ECORE_FILE_INTERVAL_STEP 0.5
|
|
|
|
#define ECORE_FILE_INTERVAL_MAX 5.0
|
|
|
|
|
|
|
|
static double _interval = ECORE_FILE_INTERVAL_MIN;
|
2005-02-20 04:17:07 -08:00
|
|
|
static Ecore_Timer *_timer = NULL;
|
|
|
|
static Evas_List *_monitors = NULL;
|
|
|
|
static int _lock = 0;
|
|
|
|
|
2005-03-29 22:35:12 -08:00
|
|
|
static int _ecore_file_monitor_poll_handler(void *data);
|
|
|
|
static void _ecore_file_monitor_poll_check(Ecore_File_Monitor *em);
|
|
|
|
static int _ecore_file_monitor_poll_checking(Ecore_File_Monitor *em, char *name);
|
2005-02-20 04:17:07 -08:00
|
|
|
|
|
|
|
int
|
2005-03-29 22:35:12 -08:00
|
|
|
ecore_file_monitor_poll_init(void)
|
2005-02-20 04:17:07 -08:00
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2005-03-29 22:35:12 -08:00
|
|
|
ecore_file_monitor_poll_shutdown(void)
|
2005-02-20 04:17:07 -08:00
|
|
|
{
|
|
|
|
Evas_List *l;
|
|
|
|
for (l = _monitors; l;)
|
|
|
|
{
|
|
|
|
Ecore_File_Monitor *em;
|
|
|
|
|
|
|
|
em = l->data;
|
|
|
|
l = l->next;
|
|
|
|
ecore_file_monitor_del(em);
|
|
|
|
}
|
|
|
|
evas_list_free(_monitors);
|
|
|
|
if (_timer)
|
|
|
|
{
|
|
|
|
ecore_timer_del(_timer);
|
|
|
|
_timer = NULL;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ecore_File_Monitor *
|
2005-03-29 22:35:12 -08:00
|
|
|
ecore_file_monitor_poll_add(const char *path,
|
|
|
|
void (*func) (void *data, Ecore_File_Monitor *em,
|
|
|
|
Ecore_File_Event event,
|
|
|
|
const char *path),
|
|
|
|
void *data)
|
2005-02-20 04:17:07 -08:00
|
|
|
{
|
|
|
|
Ecore_File_Monitor *em;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
if (!path) return NULL;
|
|
|
|
if (!func) return NULL;
|
|
|
|
|
2005-03-29 22:35:12 -08:00
|
|
|
em = calloc(1, sizeof(Ecore_File_Monitor_Poll));
|
2005-02-20 04:17:07 -08:00
|
|
|
if (!em) return NULL;
|
|
|
|
|
|
|
|
if (!_timer)
|
2005-03-29 22:35:12 -08:00
|
|
|
_timer = ecore_timer_add(_interval, _ecore_file_monitor_poll_handler, NULL);
|
2005-02-22 04:38:17 -08:00
|
|
|
else
|
|
|
|
ecore_timer_interval_set(_timer, ECORE_FILE_INTERVAL_MIN);
|
2005-02-20 04:17:07 -08:00
|
|
|
|
|
|
|
em->path = strdup(path);
|
|
|
|
len = strlen(em->path);
|
|
|
|
if (em->path[len - 1] == '/')
|
2005-02-21 08:03:08 -08:00
|
|
|
em->path[len - 1] = 0;
|
2005-02-20 04:17:07 -08:00
|
|
|
|
|
|
|
em->func = func;
|
|
|
|
em->data = data;
|
|
|
|
|
2005-03-29 22:35:12 -08:00
|
|
|
ECORE_FILE_MONITOR_POLL(em)->mtime = ecore_file_mod_time(em->path);
|
2005-02-20 04:17:07 -08:00
|
|
|
if (ecore_file_exists(em->path))
|
|
|
|
{
|
2005-03-29 22:35:12 -08:00
|
|
|
if (ecore_file_is_dir(em->path))
|
2005-02-20 04:17:07 -08:00
|
|
|
{
|
|
|
|
/* Check for subdirs */
|
2005-04-14 03:52:58 -07:00
|
|
|
Ecore_List *files;
|
|
|
|
char *file;
|
2005-02-20 04:17:07 -08:00
|
|
|
|
|
|
|
files = ecore_file_ls(em->path);
|
2005-04-14 03:52:58 -07:00
|
|
|
while ((file = ecore_list_next(files)))
|
2005-02-20 04:17:07 -08:00
|
|
|
{
|
|
|
|
Ecore_File *f;
|
|
|
|
char buf[PATH_MAX];
|
|
|
|
|
|
|
|
f = calloc(1, sizeof(Ecore_File));
|
|
|
|
if (!f)
|
|
|
|
{
|
|
|
|
free(file);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
snprintf(buf, sizeof(buf), "%s/%s", em->path, file);
|
|
|
|
f->name = file;
|
|
|
|
f->mtime = ecore_file_mod_time(buf);
|
2005-03-29 22:35:12 -08:00
|
|
|
f->is_dir = ecore_file_is_dir(buf);
|
2005-02-22 04:38:17 -08:00
|
|
|
em->files = evas_list_append(em->files, f);
|
2005-02-20 04:17:07 -08:00
|
|
|
}
|
2005-04-14 03:52:58 -07:00
|
|
|
ecore_list_destroy(files);
|
2005-02-20 04:17:07 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-03-29 22:35:12 -08:00
|
|
|
ecore_file_monitor_poll_del(em);
|
|
|
|
return NULL;
|
2005-02-20 04:17:07 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
_monitors = evas_list_append(_monitors, em);
|
|
|
|
|
|
|
|
return em;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2005-03-29 22:35:12 -08:00
|
|
|
ecore_file_monitor_poll_del(Ecore_File_Monitor *em)
|
2005-02-20 04:17:07 -08:00
|
|
|
{
|
|
|
|
Evas_List *l;
|
|
|
|
|
|
|
|
if (_lock)
|
|
|
|
{
|
2005-03-29 22:35:12 -08:00
|
|
|
ECORE_FILE_MONITOR_POLL(em)->deleted = 1;
|
2005-02-20 04:17:07 -08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Remove files */
|
2005-02-22 04:38:17 -08:00
|
|
|
for (l = em->files; l; l = l->next)
|
2005-02-20 04:17:07 -08:00
|
|
|
{
|
|
|
|
Ecore_File *f;
|
|
|
|
f = l->data;
|
|
|
|
free(f->name);
|
|
|
|
free(f);
|
|
|
|
}
|
2005-02-22 04:38:17 -08:00
|
|
|
evas_list_free(em->files);
|
2005-02-20 04:17:07 -08:00
|
|
|
|
|
|
|
_monitors = evas_list_remove(_monitors, em);
|
|
|
|
free(em->path);
|
|
|
|
free(em);
|
|
|
|
|
|
|
|
if ((!_monitors) && (_timer))
|
|
|
|
{
|
|
|
|
ecore_timer_del(_timer);
|
|
|
|
_timer = NULL;
|
|
|
|
}
|
2005-02-22 04:38:17 -08:00
|
|
|
else
|
|
|
|
ecore_timer_interval_set(_timer, ECORE_FILE_INTERVAL_MIN);
|
2005-02-20 04:17:07 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2005-03-29 22:35:12 -08:00
|
|
|
_ecore_file_monitor_poll_handler(void *data __UNUSED__)
|
2005-02-20 04:17:07 -08:00
|
|
|
{
|
|
|
|
Evas_List *monitor;
|
|
|
|
|
2005-02-22 04:38:17 -08:00
|
|
|
_interval += ECORE_FILE_INTERVAL_STEP;
|
2005-02-20 04:17:07 -08:00
|
|
|
_lock = 1;
|
|
|
|
for (monitor = _monitors; monitor;)
|
|
|
|
{
|
|
|
|
Ecore_File_Monitor *em;
|
|
|
|
|
|
|
|
em = monitor->data;
|
|
|
|
monitor = monitor->next;
|
2005-03-29 22:35:12 -08:00
|
|
|
_ecore_file_monitor_poll_check(em);
|
2005-02-20 04:17:07 -08:00
|
|
|
}
|
|
|
|
_lock = 0;
|
2005-02-22 04:38:17 -08:00
|
|
|
if (_interval > ECORE_FILE_INTERVAL_MAX)
|
|
|
|
_interval = ECORE_FILE_INTERVAL_MAX;
|
|
|
|
ecore_timer_interval_set(_timer, _interval);
|
|
|
|
|
2005-02-20 04:17:07 -08:00
|
|
|
for (monitor = _monitors; monitor;)
|
|
|
|
{
|
|
|
|
Ecore_File_Monitor *em;
|
|
|
|
|
|
|
|
em = monitor->data;
|
|
|
|
monitor = monitor->next;
|
2005-03-29 22:35:12 -08:00
|
|
|
if (ECORE_FILE_MONITOR_POLL(em)->deleted)
|
2005-02-20 04:17:07 -08:00
|
|
|
ecore_file_monitor_del(em);
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2005-03-29 22:35:12 -08:00
|
|
|
_ecore_file_monitor_poll_check(Ecore_File_Monitor *em)
|
2005-02-20 04:17:07 -08:00
|
|
|
{
|
|
|
|
int mtime;
|
2005-03-29 22:35:12 -08:00
|
|
|
int is_dir;
|
2005-02-20 04:17:07 -08:00
|
|
|
|
|
|
|
mtime = ecore_file_mod_time(em->path);
|
2005-03-29 22:35:12 -08:00
|
|
|
is_dir = ecore_file_is_dir(em->path);
|
|
|
|
if (mtime < ECORE_FILE_MONITOR_POLL(em)->mtime)
|
|
|
|
{
|
|
|
|
Evas_List *l;
|
|
|
|
Ecore_File_Event event;
|
|
|
|
|
|
|
|
/* Notify all files deleted */
|
|
|
|
for (l = em->files; l;)
|
|
|
|
{
|
|
|
|
Ecore_File *f;
|
|
|
|
char buf[PATH_MAX];
|
|
|
|
|
|
|
|
f = l->data;
|
|
|
|
l = l->next;
|
|
|
|
snprintf(buf, sizeof(buf), "%s/%s", em->path, f->name);
|
|
|
|
if (f->is_dir)
|
|
|
|
event = ECORE_FILE_EVENT_DELETED_DIRECTORY;
|
|
|
|
else
|
|
|
|
event = ECORE_FILE_EVENT_DELETED_FILE;
|
|
|
|
em->func(em->data, em, event, buf);
|
|
|
|
free(f->name);
|
|
|
|
free(f);
|
|
|
|
}
|
|
|
|
em->files = evas_list_free(em->files);
|
|
|
|
em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path);
|
|
|
|
_interval = ECORE_FILE_INTERVAL_MIN;
|
|
|
|
}
|
|
|
|
else
|
2005-02-20 04:17:07 -08:00
|
|
|
{
|
2005-03-29 22:35:12 -08:00
|
|
|
Evas_List *l;
|
|
|
|
|
|
|
|
/* Check for changed files */
|
|
|
|
for (l = em->files; l;)
|
|
|
|
{
|
|
|
|
Ecore_File *f;
|
|
|
|
char buf[PATH_MAX];
|
|
|
|
int mtime;
|
|
|
|
Ecore_File_Event event;
|
|
|
|
|
|
|
|
f = l->data;
|
|
|
|
l = l->next;
|
|
|
|
snprintf(buf, sizeof(buf), "%s/%s", em->path, f->name);
|
|
|
|
mtime = ecore_file_mod_time(buf);
|
|
|
|
if (mtime < f->mtime)
|
|
|
|
{
|
|
|
|
if (f->is_dir)
|
|
|
|
event = ECORE_FILE_EVENT_DELETED_DIRECTORY;
|
|
|
|
else
|
|
|
|
event = ECORE_FILE_EVENT_DELETED_FILE;
|
|
|
|
|
|
|
|
em->func(em->data, em, event, buf);
|
|
|
|
em->files = evas_list_remove(em->files, f);
|
|
|
|
free(f->name);
|
|
|
|
free(f);
|
|
|
|
_interval = ECORE_FILE_INTERVAL_MIN;
|
|
|
|
}
|
|
|
|
else if ((mtime > f->mtime) && !(f->is_dir))
|
|
|
|
{
|
|
|
|
em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, buf);
|
|
|
|
_interval = ECORE_FILE_INTERVAL_MIN;
|
|
|
|
}
|
|
|
|
f->mtime = mtime;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check for new files */
|
|
|
|
if (ECORE_FILE_MONITOR_POLL(em)->mtime < mtime)
|
|
|
|
{
|
2005-04-14 03:52:58 -07:00
|
|
|
Ecore_List *files;
|
|
|
|
char *file;
|
2005-03-29 22:35:12 -08:00
|
|
|
|
|
|
|
/* Files have been added or removed */
|
|
|
|
files = ecore_file_ls(em->path);
|
2005-04-14 03:52:58 -07:00
|
|
|
while ((file = ecore_list_next(files)))
|
2005-03-29 22:35:12 -08:00
|
|
|
{
|
|
|
|
Ecore_File *f;
|
|
|
|
char buf[PATH_MAX];
|
|
|
|
Ecore_File_Event event;
|
|
|
|
|
|
|
|
if (_ecore_file_monitor_poll_checking(em, file))
|
|
|
|
{
|
|
|
|
free(file);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
snprintf(buf, sizeof(buf), "%s/%s", em->path, file);
|
|
|
|
f = calloc(1, sizeof(Ecore_File));
|
|
|
|
if (!f)
|
|
|
|
{
|
|
|
|
free(file);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
f->name = file;
|
|
|
|
f->mtime = ecore_file_mod_time(buf);
|
|
|
|
f->is_dir = ecore_file_is_dir(buf);
|
|
|
|
if (f->is_dir)
|
|
|
|
event = ECORE_FILE_EVENT_CREATED_DIRECTORY;
|
|
|
|
else
|
|
|
|
event = ECORE_FILE_EVENT_CREATED_FILE;
|
|
|
|
em->func(em->data, em, event, buf);
|
|
|
|
em->files = evas_list_append(em->files, f);
|
|
|
|
}
|
2005-04-14 03:52:58 -07:00
|
|
|
ecore_list_destroy(files);
|
2005-03-29 22:35:12 -08:00
|
|
|
if (!ecore_file_is_dir(em->path))
|
|
|
|
em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, em->path);
|
|
|
|
_interval = ECORE_FILE_INTERVAL_MIN;
|
|
|
|
}
|
2005-02-20 04:17:07 -08:00
|
|
|
}
|
2005-03-29 22:35:12 -08:00
|
|
|
ECORE_FILE_MONITOR_POLL(em)->mtime = mtime;
|
2005-02-20 04:17:07 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2005-03-29 22:35:12 -08:00
|
|
|
_ecore_file_monitor_poll_checking(Ecore_File_Monitor *em, char *name)
|
2005-02-20 04:17:07 -08:00
|
|
|
{
|
|
|
|
Evas_List *l;
|
|
|
|
|
2005-02-22 04:38:17 -08:00
|
|
|
for (l = em->files; l; l = l->next)
|
2005-02-20 04:17:07 -08:00
|
|
|
{
|
|
|
|
Ecore_File *f;
|
|
|
|
|
|
|
|
f = l->data;
|
|
|
|
if (!strcmp(f->name, name))
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|