From 40ec35d38dcbf577489f43bc3988b27914bfbdc6 Mon Sep 17 00:00:00 2001 From: sebastid Date: Wed, 30 Mar 2005 06:35:12 +0000 Subject: [PATCH] Inotify monitoring almost works now. Since inotify seems to be the future, I changed the interface of monitoring to be more like inotify. SVN revision: 13984 --- legacy/ecore/configure.in | 84 ++++- legacy/ecore/src/lib/ecore_file/Ecore_File.h | 46 +-- legacy/ecore/src/lib/ecore_file/Makefile.am | 2 - .../src/lib/ecore_file/ecore_file_monitor.c | 122 ++++++- .../ecore_file/ecore_file_monitor_dnotify.c | 322 ----------------- .../lib/ecore_file/ecore_file_monitor_fam.c | 215 ++++++----- .../ecore_file/ecore_file_monitor_inotify.c | 331 +++++++---------- .../lib/ecore_file/ecore_file_monitor_poll.c | 334 ++++++++---------- .../src/lib/ecore_file/ecore_file_private.h | 55 ++- 9 files changed, 635 insertions(+), 876 deletions(-) delete mode 100644 legacy/ecore/src/lib/ecore_file/ecore_file_monitor_dnotify.c diff --git a/legacy/ecore/configure.in b/legacy/ecore/configure.in index b34a3679b0..d4dd19f340 100644 --- a/legacy/ecore/configure.in +++ b/legacy/ecore/configure.in @@ -738,14 +738,16 @@ else AM_CONDITIONAL(BUILD_ECORE_CONFIG, false) fi -AC_MSG_CHECKING(wheter ecore_file module is to be built) - have_ecore_file="no" ecore_file_libs="" +use_fam="no" +use_inotify="no" +use_poll="no" +AC_MSG_CHECKING(wheter ecore_file module is to be built) AC_ARG_ENABLE(ecore-file, [ --disable-ecore-file disable the ecore_file module], [ - if [ test "$enableval" = "yes" ]; then + if test "$enableval" = "yes"; then AC_MSG_RESULT(yes) have_ecore_file="yes" else @@ -757,13 +759,49 @@ AC_ARG_ENABLE(ecore-file, ] ) +AC_MSG_CHECKING(wheter inotify is to be used for filemonitoring) +AC_ARG_ENABLE(inotify, +[ --disable-inotify disable inotify in the ecore_file module], [ + if test "$enableval" = "yes"; then + AC_MSG_RESULT(yes) + use_inotify="yes" + else + AC_MSG_RESULT(no) + fi +], [ + AC_MSG_RESULT(yes) + use_inotify="yes" +] +) + +if test "x$use_inotify" = "xyes"; then + AC_CHECK_HEADER(linux/inotify.h, + [ + AC_DEFINE(HAVE_INOTIFY, 1, [ File monitoring with Inotify ]) + use_inotify="yes" + ], [ + use_inotify="no" + ] + ) +fi + +#AC_MSG_CHECKING(wheter FAM is to be used for filemonitoring) +#AC_ARG_ENABLE(fam, +#[ --disable-fam disable fam in the ecore_file module], [ +# if test "$enableval" = "yes"; then +# AC_MSG_RESULT(yes) +# use_fam="yes" +# else +# AC_MSG_RESULT(no) +# fi +#], [ +# AC_MSG_RESULT(yes) +# use_fam="yes" +#] +#) + fam_libs="" -if [ test "x$have_ecore_file" = "xyes" ]; then - AM_CONDITIONAL(BUILD_ECORE_FILE, true) - ecore_file_libs="-lecore_file" - AC_DEFINE(HAVE_POLL, 1, [ File monitoring with polling ]) -# I'm to stupid to get fam working right :) -# PKG_CHECK_MODULES(FAM, gamin >= 0.0.23, +#if test "x$use_fam" = "xyes"; then # AC_CHECK_LIB(fam, FAMOpen, # [ # AC_DEFINE(HAVE_FAM, 1, [ File monitoring with FAM ]) @@ -773,6 +811,31 @@ if [ test "x$have_ecore_file" = "xyes" ]; then # use_fam="no" # ] # ) +#fi + +AC_MSG_CHECKING(wheter polling is to be used for filemonitoring) +AC_ARG_ENABLE(poll, +[ --disable-poll disable poll in the ecore_file module], [ + if test "$enableval" = "yes"; then + AC_MSG_RESULT(yes) + use_poll="yes" + else + AC_MSG_RESULT(no) + fi +], [ + AC_MSG_RESULT(yes) + use_poll="yes" +] +) + +if test "x$use_poll" = "xyes"; then + AC_DEFINE(HAVE_POLL, 1, [ File monitoring with polling ]) +fi + +if test "x$have_ecore_file" = "xyes"; then + AM_CONDITIONAL(BUILD_ECORE_FILE, true) + ecore_file_libs="-lecore_file" + AC_DEFINE(HAVE_POLL, 1, [ File monitoring with polling ]) else AM_CONDITIONAL(BUILD_ECORE_FILE, false) fi @@ -884,7 +947,8 @@ echo " Ecore_Evas FB Support...: $have_ecore_evas_fb" echo " Ecore_Buffer............: $have_ecore_evas_buffer" echo " Ecore_Ipc...............: $have_ecore_ipc (OpenSSL: $use_openssl)" echo " Ecore_Config............: $have_ecore_config" -echo " Ecore_File..............: $have_ecore_file (FAM: $use_fam)" +#echo " Ecore_File..............: $have_ecore_file (Inotify: $use_inotify) (FAM: $use_fam) (Poll: $use_poll)" +echo " Ecore_File..............: $have_ecore_file (Inotify: $use_inotify) (Poll: $use_poll)" echo echo "Now type 'make' ('gmake' on some systems) to compile $PACKAGE." echo diff --git a/legacy/ecore/src/lib/ecore_file/Ecore_File.h b/legacy/ecore/src/lib/ecore_file/Ecore_File.h index 0a58cbcedc..476e2efe0a 100644 --- a/legacy/ecore/src/lib/ecore_file/Ecore_File.h +++ b/legacy/ecore/src/lib/ecore_file/Ecore_File.h @@ -48,54 +48,24 @@ EAPI Evas_List *ecore_file_ls (const char *dir); typedef struct _Ecore_File_Monitor Ecore_File_Monitor; typedef struct _Ecore_File_Monitor_Event Ecore_File_Monitor_Event; -typedef enum { - ECORE_FILE_TYPE_NONE, - ECORE_FILE_TYPE_FILE, - ECORE_FILE_TYPE_DIRECTORY -} Ecore_File_Type; - typedef enum { ECORE_FILE_EVENT_NONE, - ECORE_FILE_EVENT_EXISTS, - ECORE_FILE_EVENT_CREATED, - ECORE_FILE_EVENT_DELETED, - ECORE_FILE_EVENT_CHANGED + ECORE_FILE_EVENT_CREATED_FILE, + ECORE_FILE_EVENT_CREATED_DIRECTORY, + ECORE_FILE_EVENT_DELETED_FILE, + ECORE_FILE_EVENT_DELETED_DIRECTORY, + ECORE_FILE_EVENT_DELETED_SELF, + ECORE_FILE_EVENT_MODIFIED } Ecore_File_Event; -#if 0 -struct _Ecore_File_Monitor { - void (*func) (void *data, - Ecore_File_Monitor *ecore_file_monitor, - Ecore_File_Type type, - Ecore_File_Event event, - const char *path); - - char *path; - Ecore_File_Type type; - void *data; -}; -#endif - -#if 0 -struct _Ecore_File_Monitor_Event { - Ecore_File_Monitor *ecore_file_monitor; - Ecore_File_Type type; - Ecore_File_Event event; - char *path; - void *data; -}; -#endif - -#define ECORE_FILE_MONITOR(x) ((Ecore_File_Monitor *)(x)) - EAPI Ecore_File_Monitor *ecore_file_monitor_add(const char *path, void (*func) (void *data, Ecore_File_Monitor *ecore_file_monitor, - Ecore_File_Type type, Ecore_File_Event event, const char *path), void *data); EAPI void ecore_file_monitor_del(Ecore_File_Monitor *ecore_file_monitor); -EAPI Ecore_File_Type ecore_file_monitor_type_get(Ecore_File_Monitor *ecore_file_monitor); +EAPI const char *ecore_file_monitor_path_get(Ecore_File_Monitor *ecore_file_monitor); + #endif diff --git a/legacy/ecore/src/lib/ecore_file/Makefile.am b/legacy/ecore/src/lib/ecore_file/Makefile.am index 8a168ac6cd..76c49d5263 100644 --- a/legacy/ecore/src/lib/ecore_file/Makefile.am +++ b/legacy/ecore/src/lib/ecore_file/Makefile.am @@ -19,7 +19,6 @@ ecore_file_private.h \ ecore_file_monitor.c \ ecore_file_monitor_fam.c \ ecore_file_monitor_inotify.c \ -ecore_file_monitor_dnotify.c \ ecore_file_monitor_poll.c libecore_file_la_LIBADD = \ @@ -35,6 +34,5 @@ ecore_file_private.h \ ecore_file_monitor.c \ ecore_file_monitor_fam.c \ ecore_file_monitor_inotify.c \ -ecore_file_monitor_dnotify.c \ ecore_file_monitor_poll.c diff --git a/legacy/ecore/src/lib/ecore_file/ecore_file_monitor.c b/legacy/ecore/src/lib/ecore_file/ecore_file_monitor.c index 0573b630fc..e270e01a63 100644 --- a/legacy/ecore/src/lib/ecore_file/ecore_file_monitor.c +++ b/legacy/ecore/src/lib/ecore_file/ecore_file_monitor.c @@ -3,8 +3,124 @@ */ #include "ecore_file_private.h" -Ecore_File_Type -ecore_file_monitor_type_get(Ecore_File_Monitor *em) +typedef enum { + ECORE_FILE_MONITOR_TYPE_NONE, +#ifdef HAVE_INOTIFY + ECORE_FILE_MONITOR_TYPE_INOTIFY, +#endif +#ifdef HAVE_FAM + ECORE_FILE_MONITOR_TYPE_FAM, +#endif +#ifdef HAVE_POLL + ECORE_FILE_MONITOR_TYPE_POLL +#endif +} Ecore_File_Monitor_Type; + +static Ecore_File_Monitor_Type monitor_type = ECORE_FILE_MONITOR_TYPE_NONE; + +int +ecore_file_monitor_init(void) { - return em->type; +#ifdef HAVE_INOTIFY +#if 0 + monitor_type = ECORE_FILE_MONITOR_TYPE_INOTIFY; + if (ecore_file_monitor_inotify_init()) + return 1; +#endif +#endif +#ifdef HAVE_FAM +#if 0 + monitor_type = ECORE_FILE_MONITOR_TYPE_FAM; + if (ecore_file_monitor_fam_init()) + return 1; +#endif +#endif +#ifdef HAVE_POLL + monitor_type = ECORE_FILE_MONITOR_TYPE_POLL; + if (ecore_file_monitor_poll_init()) + return 1; +#endif + monitor_type = ECORE_FILE_MONITOR_TYPE_NONE; + return 0; +} + +int +ecore_file_monitor_shutdown(void) +{ + switch (monitor_type) + { + case ECORE_FILE_MONITOR_TYPE_NONE: + return 1; +#ifdef HAVE_INOTIFY + case ECORE_FILE_MONITOR_TYPE_INOTIFY: + return ecore_file_monitor_inotify_shutdown(); +#endif +#ifdef HAVE_FAM + case ECORE_FILE_MONITOR_TYPE_FAM: + return ecore_file_monitor_fam_shutdown(); +#endif +#ifdef HAVE_POLL + case ECORE_FILE_MONITOR_TYPE_POLL: + return ecore_file_monitor_poll_shutdown(); +#endif + } + return 0; +} + +Ecore_File_Monitor * +ecore_file_monitor_add(const char *path, + void (*func) (void *data, Ecore_File_Monitor *em, + Ecore_File_Event event, + const char *path), + void *data) +{ + switch (monitor_type) + { + case ECORE_FILE_MONITOR_TYPE_NONE: + return NULL; +#ifdef HAVE_INOTIFY + case ECORE_FILE_MONITOR_TYPE_INOTIFY: + return ecore_file_monitor_inotify_add(path, func, data); +#endif +#ifdef HAVE_FAM + case ECORE_FILE_MONITOR_TYPE_FAM: + return ecore_file_monitor_fam_add(path, func, data); +#endif +#ifdef HAVE_POLL + case ECORE_FILE_MONITOR_TYPE_POLL: + return ecore_file_monitor_poll_add(path, func, data); +#endif + } + return NULL; +} + +void +ecore_file_monitor_del(Ecore_File_Monitor *em) +{ + switch (monitor_type) + { + case ECORE_FILE_MONITOR_TYPE_NONE: + break; +#ifdef HAVE_INOTIFY + case ECORE_FILE_MONITOR_TYPE_INOTIFY: + ecore_file_monitor_inotify_del(em); + break; +#endif +#ifdef HAVE_FAM + case ECORE_FILE_MONITOR_TYPE_FAM: + ecore_file_monitor_fam_del(em); + break; +#endif +#ifdef HAVE_POLL + case ECORE_FILE_MONITOR_TYPE_POLL: + ecore_file_monitor_poll_del(em); + break; +#endif + } +} + +const char * +ecore_file_monitor_path_get(Ecore_File_Monitor *em) +{ + return em->path; } diff --git a/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_dnotify.c b/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_dnotify.c deleted file mode 100644 index caa7e25dab..0000000000 --- a/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_dnotify.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 - */ -#include "ecore_file_private.h" - -/* - * TODO: - * - Check the return value from fcntl. - * - Try different realtime numbers if one fail. - * - Doesn't work right! - * - Misses fileupdates - * - Misses filedeletions - */ - -#ifdef HAVE_DNOTIFY - -#include - -typedef struct _Ecore_File_Monitor_Dnotify Ecore_File_Monitor_Dnotify; -typedef struct _Ecore_File Ecore_File; - -#define ECORE_FILE_MONITOR_DNOTIFY(x) ((Ecore_File_Monitor_Dnotify *)(x)) - -struct _Ecore_File_Monitor_Dnotify -{ - Ecore_File_Monitor monitor; - int fd; - Evas_List *files; - unsigned char deleted; -}; - -struct _Ecore_File -{ - char *name; - int mtime; - Ecore_File_Type type; -}; - -static Ecore_Event_Handler *_eh; -static Evas_List *_monitors = NULL; -static int _lock = 0; - -static int _ecore_file_monitor_handler(void *data, int type, void *event); -static void _ecore_file_monitor_check(Ecore_File_Monitor *em); -static int _ecore_file_monitor_checking(Ecore_File_Monitor *em, char *path); - -int -ecore_file_monitor_init(void) -{ - _eh = ecore_event_handler_add(ECORE_EVENT_SIGNAL_REALTIME, _ecore_file_monitor_handler, NULL); - return 1; -} - -int -ecore_file_monitor_shutdown(void) -{ - Evas_List *l; - - if (_eh) ecore_event_handler_del(_eh); - for (l = _monitors; l;) - { - Ecore_File_Monitor *em; - - em = l->data; - l = l->next; - ecore_file_monitor_del(em); - } - evas_list_free(_monitors); - return 1; -} - -Ecore_File_Monitor * -ecore_file_monitor_add(const char *path, - void (*func) (void *data, Ecore_File_Monitor *em, - Ecore_File_Type type, - Ecore_File_Event event, - const char *path), - void *data) -{ - Ecore_File_Monitor *em; - Ecore_File_Monitor_Dnotify *emd; - int len; - - if (!path) return NULL; - if (!func) return NULL; - - emd = calloc(1, sizeof(Ecore_File_Monitor_Dnotify)); - em = ECORE_FILE_MONITOR(emd); - if (!em) return NULL; - - em->func = func; - em->data = data; - - em->path = strdup(path); - len = strlen(em->path); - if (em->path[len - 1] == '/') - em->path[len - 1] = '\0'; - - if (ecore_file_exists(em->path)) - { - em->type = ecore_file_is_dir(em->path) ? - ECORE_FILE_TYPE_DIRECTORY : - ECORE_FILE_TYPE_FILE; - - if (em->type == ECORE_FILE_TYPE_DIRECTORY) - { - /* Check for subdirs */ - Evas_List *files, *l; - - files = ecore_file_ls(em->path); - for (l = files; l; l = l->next) - { - Ecore_File *f; - char *file; - char buf[PATH_MAX]; - - file = l->data; - 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); - f->type = ecore_file_is_dir(buf) ? - ECORE_FILE_TYPE_DIRECTORY : - ECORE_FILE_TYPE_FILE; - em->func(em->data, em, f->type, ECORE_FILE_EVENT_EXISTS, buf); - emd->files = evas_list_append(emd->files, f); - } - evas_list_free(files); - - emd->fd = open(em->path, O_RDONLY); - if (fcntl(emd->fd, F_SETSIG, SIGRTMIN + 1)) - printf("ERROR: F_SETSIG\n"); - if (fcntl(emd->fd, F_NOTIFY, DN_ACCESS|DN_MODIFY|DN_CREATE|DN_DELETE|DN_MULTISHOT)) - printf("ERROR: F_NOTIFY\n"); - } - else - { - /* TODO: We do not support monitoring files! */ - free(em); - return NULL; - } - } - else - { - em->type = ECORE_FILE_TYPE_NONE; - em->func(em->data, em, em->type, ECORE_FILE_EVENT_DELETED, em->path); - } - - _monitors = evas_list_append(_monitors, em); - - return em; -} - -void -ecore_file_monitor_del(Ecore_File_Monitor *em) -{ - Ecore_File_Monitor_Dnotify *emd; - Evas_List *l; - - emd = ECORE_FILE_MONITOR_DNOTIFY(em); - if (_lock) - { - emd->deleted = 1; - return; - } - close(emd->fd); - /* Remove files */ - for (l = emd->files; l; l = l->next) - { - Ecore_File *f; - f = l->data; - free(f->name); - free(f); - } - evas_list_free(emd->files); - - _monitors = evas_list_remove(_monitors, em); - free(em->path); - free(em); -} - -static int -_ecore_file_monitor_handler(void *data, int type, void *event) -{ - Ecore_Event_Signal_Realtime *ev; - Evas_List *monitor; - - ev = event; - _lock = 1; - for (monitor = _monitors; monitor;) - { - Ecore_File_Monitor *em; - Ecore_File_Monitor_Dnotify *emd; - - em = monitor->data; - emd = ECORE_FILE_MONITOR_DNOTIFY(em); - monitor = monitor->next; - - if (emd->fd == ev->data.si_fd) - _ecore_file_monitor_check(em); - } - _lock = 0; - for (monitor = _monitors; monitor;) - { - Ecore_File_Monitor *em; - Ecore_File_Monitor_Dnotify *emd; - - em = monitor->data; - emd = ECORE_FILE_MONITOR_DNOTIFY(em); - monitor = monitor->next; - - if (emd->deleted) - ecore_file_monitor_del(em); - } - return 1; -} - -#if 0 -static Ecore_File_Monitor_Request * -_ecore_file_monitor_request_find(Ecore_File_Monitor *em, char *path) -{ - Evas_List *l; - - for (l = em->requests; l; l = l->next) - { - Ecore_File_Monitor_Request *er; - - er = l->data; - if (!strcmp(er->path, path)) - return er; - } - return NULL; -} -#endif - -static void -_ecore_file_monitor_check(Ecore_File_Monitor *em) -{ - Ecore_File_Monitor_Dnotify *emd; - Evas_List *files, *l; - - /* Check for changed files */ - emd = ECORE_FILE_MONITOR_DNOTIFY(em); - for (l = emd->files; l;) - { - Ecore_File *f; - char buf[PATH_MAX]; - int mtime; - - 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) - { - em->func(em->data, em, f->type, ECORE_FILE_EVENT_DELETED, buf); - emd->files = evas_list_remove(emd->files, f); - free(f->name); - free(f); - } - else if (mtime > f->mtime) - em->func(em->data, em, f->type, ECORE_FILE_EVENT_CHANGED, buf); - f->mtime = mtime; - } - - files = ecore_file_ls(em->path); - for (l = files; l; l = l->next) - { - Ecore_File *f; - char *file; - char buf[PATH_MAX]; - - file = l->data; - if (_ecore_file_monitor_checking(em, file)) - { - free(file); - continue; - } - - 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); - f->type = ecore_file_is_dir(buf) ? - ECORE_FILE_TYPE_DIRECTORY : - ECORE_FILE_TYPE_FILE; - em->func(em->data, em, f->type, ECORE_FILE_EVENT_CREATED, buf); - emd->files = evas_list_append(emd->files, f); - } -} - -static int -_ecore_file_monitor_checking(Ecore_File_Monitor *em, char *name) -{ - Ecore_File_Monitor_Dnotify *emd; - Evas_List *l; - - emd = ECORE_FILE_MONITOR_DNOTIFY(em); - for (l = emd->files; l; l = l->next) - { - Ecore_File *f; - - f = l->data; - if (!strcmp(f->name, name)) - return 1; - } - - return 0; -} -#endif diff --git a/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_fam.c b/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_fam.c index ca00658efc..d9837c096b 100644 --- a/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_fam.c +++ b/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_fam.c @@ -6,7 +6,7 @@ /* * TODO: * - When several subdirectories are created really fast, the code - * doesn't keep up! Putting in a random printf() makes it work.. + * doesn't keep up! * - Same for deletion of files in deleted directories! */ @@ -17,48 +17,46 @@ typedef struct _Ecore_File_Monitor_Fam Ecore_File_Monitor_Fam; typedef struct _Ecore_File Ecore_File; +#define ECORE_FILE_MONITOR_FAM(x) ((Ecore_File_Monitor_Fam *)(x)) + struct _Ecore_File_Monitor_Fam { - Ecore_File_Monitor monitor; + Ecore_File_Monitor monitor; FAMRequest *request; - Evas_List *files; }; struct _Ecore_File { - char *name; - Ecore_File_Type type; + char *name; }; -#define ECORE_FILE_MONITOR_FAM(x) ((Ecore_File_Monitor_Fam *)(x)) - static Ecore_Fd_Handler *_fdh = NULL; static FAMConnection *_fc = NULL; static Evas_List *_monitors = NULL; -static int _ecore_file_monitor_handler(void *data, Ecore_Fd_Handler *fdh); -static Ecore_File * _ecore_file_monitor_file_find(Ecore_File_Monitor *em, char *name); -static Ecore_File_Event _ecore_file_monitor_event_get(FAMCodes change); +static int _ecore_file_monitor_fam_handler(void *data, Ecore_Fd_Handler *fdh); +static Ecore_File *_ecore_file_monitor_fam_file_find(Ecore_File_Monitor *em, char *name); +static Ecore_File_Event _ecore_file_monitor_fam_event_get(FAMCodes code, int self, int is_dir); int -ecore_file_monitor_init(void) +ecore_file_monitor_fam_init(void) { _fc = calloc(1, sizeof(FAMConnection)); if (!_fc) return 0; FAMOpen(_fc); - _fdh = ecore_main_fd_handler_add(FAMCONNECTION_GETFD(_fc), ECORE_FD_READ, _ecore_file_monitor_handler, - NULL, NULL, NULL); + _fdh = ecore_main_fd_handler_add(FAMCONNECTION_GETFD(_fc), ECORE_FD_READ, + _ecore_file_monitor_fam_handler, NULL, NULL, NULL); return 1; } int -ecore_file_monitor_shutdown(void) +ecore_file_monitor_fam_shutdown(void) { Evas_List *l; for (l = _monitors; l; l = l->next) - ecore_file_monitor_del(ECORE_FILE_MONITOR(l->data)); + ecore_file_monitor_fam_del(ECORE_FILE_MONITOR(l->data)); evas_list_free(_monitors); if (_fdh) ecore_main_fd_handler_del(_fdh); if (_fc) @@ -70,67 +68,61 @@ ecore_file_monitor_shutdown(void) } Ecore_File_Monitor * -ecore_file_monitor_add(const char *path, - void (*func) (void *data, - Ecore_File_Monitor *em, - Ecore_File_Type type, - Ecore_File_Event event, - const char *path), - void *data) +ecore_file_monitor_fam_add(const char *path, + void (*func) (void *data, + Ecore_File_Monitor *em, + Ecore_File_Event event, + const char *path), + void *data) { Ecore_File_Monitor *em; - Ecore_File_Monitor_Fam *emf; int len; - emf = calloc(1, sizeof(Ecore_File_Monitor_Fam)); - em = ECORE_FILE_MONITOR(emf); + em = calloc(1, sizeof(Ecore_File_Monitor_Fam)); if (!em) return NULL; em->func = func; em->data = data; - _monitors = evas_list_append(_monitors, em); - em->path = strdup(path); len = strlen(em->path); if (em->path[len - 1] == '/') - em->path[len - 1] = '\0'; + em->path[len - 1] = 0; if (ecore_file_exists(em->path)) { - em->type = ecore_file_is_dir(em->path) ? - ECORE_FILE_TYPE_DIRECTORY : - ECORE_FILE_TYPE_FILE; - - /* TODO: Check if calloc succeded! */ - emf->request = calloc(1, sizeof(FAMRequest)); - if (em->type == ECORE_FILE_TYPE_DIRECTORY) + ECORE_FILE_MONITOR_FAM(em)->request = calloc(1, sizeof(FAMRequest)); + if (!ECORE_FILE_MONITOR_FAM(em)->request) { - FAMMonitorDirectory(_fc, em->path, emf->request, em); + ecore_file_monitor_fam_del(em); + return NULL; + } + if (ecore_file_is_dir(em->path)) + { + FAMMonitorDirectory(_fc, em->path, ECORE_FILE_MONITOR_FAM(em)->request, em); } else { - FAMMonitorFile(_fc, em->path, emf->request, em); - em->func(em->data, em, em->type, ECORE_FILE_EVENT_EXISTS, em->path); + FAMMonitorFile(_fc, em->path, ECORE_FILE_MONITOR_FAM(em)->request, em); } } else { - em->type = ECORE_FILE_TYPE_NONE; - em->func(em->data, em, em->type, ECORE_FILE_EVENT_DELETED, em->path); + ecore_file_monitor_fam_del(em); + return NULL; } + _monitors = evas_list_append(_monitors, em); + return em; } void -ecore_file_monitor_del(Ecore_File_Monitor *em) +ecore_file_monitor_fam_del(Ecore_File_Monitor *em) { - Ecore_File_Monitor_Fam *emf; Evas_List *l; - emf = ECORE_FILE_MONITOR_FAM(em); - for (l = emf->files; l; l = l->next) + for (l = em->files; l; l = l->next) { Ecore_File *f; @@ -138,18 +130,21 @@ ecore_file_monitor_del(Ecore_File_Monitor *em) free(f->name); free(f); } - evas_list_free(emf->files); + evas_list_free(em->files); _monitors = evas_list_remove(_monitors, em); - FAMCancelMonitor(_fc, emf->request); - free(emf->request); + if (ECORE_FILE_MONITOR_FAM(em)->request) + { + FAMCancelMonitor(_fc, ECORE_FILE_MONITOR_FAM(em)->request); + free(ECORE_FILE_MONITOR_FAM(em)->request); + } free(em->path); free(em); } static int -_ecore_file_monitor_handler(void *data, Ecore_Fd_Handler *fdh) +_ecore_file_monitor_fam_handler(void *data, Ecore_Fd_Handler *fdh) { int pending, i; @@ -158,62 +153,107 @@ _ecore_file_monitor_handler(void *data, Ecore_Fd_Handler *fdh) for (i = 0; i < pending; i++) { Ecore_File_Monitor *em; - Ecore_File_Monitor_Fam *emf; FAMEvent fe; Ecore_File_Event event; char buf[PATH_MAX]; + int len, self; + + buf[0] = 0; FAMNextEvent(_fc, &fe); - event = _ecore_file_monitor_event_get(fe.code); + len = strlen(fe.filename); + if (fe.filename[len - 1] == '/') + fe.filename[len - 1] = 0; + self = !strcmp(em->path, fe.filename); + if (!self) + snprintf(buf, sizeof(buf), "%s/%s", em->path, fe.filename); + + event = _ecore_file_monitor_fam_event_get(fe.code, self, ecore_file_is_dir(buf)); em = fe.userdata; - emf = ECORE_FILE_MONITOR_FAM(em); if (!em) continue; if (event == ECORE_FILE_EVENT_NONE) continue; - if ((em->type == ECORE_FILE_TYPE_DIRECTORY) - && !strcmp(em->path, fe.filename)) - continue; - /* Create path */ - snprintf(buf, sizeof(buf), "%s/%s", em->path, fe.filename); - if (event == ECORE_FILE_EVENT_DELETED) +#if 0 + if (!strcmp(em->path, fe.filename)) { - Ecore_File *f; + Evas_List *l; - f = _ecore_file_monitor_file_find(em, fe.filename); - if (f) + if (event == ECORE_FILE_EVENT_DELETED) { - emf->files = evas_list_remove(emf->files, f); - em->func(em->data, em, f->type, event, buf); - free(f->name); - free(f); + /* 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); + em->func(em->data, em, f->type, ECORE_FILE_EVENT_DELETED, buf); + free(f->name); + free(f); + } + em->files = evas_list_free(em->files); + em->func(em->data, em, em->type, event, em->path); + em->type = ECORE_FILE_TYPE_NONE; + } + else + { + em->func(em->data, em, em->type, event, em->path); } } else { Ecore_File *f; - f = calloc(1, sizeof(Ecore_File)); - if (!f) continue; + switch (event) + { + case ECORE_FILE_EVENT_NONE: + break; + case ECORE_FILE_EVENT_EXISTS: + f = _ecore_file_monitor_fam_file_find(em, fe.filename); + if (f) + { + em->func(em->data, em, f->type, event, buf); + break; + } + case ECORE_FILE_EVENT_CREATED: + f = calloc(1, sizeof(Ecore_File)); + if (!f) break; - f->type = ecore_file_is_dir(buf) ? - ECORE_FILE_TYPE_DIRECTORY : - ECORE_FILE_TYPE_FILE; - f->name = strdup(fe.filename); - emf->files = evas_list_append(emf->files, f); - em->func(em->data, em, f->type, event, buf); + f->type = ecore_file_is_dir(buf) ? + ECORE_FILE_TYPE_DIRECTORY : + ECORE_FILE_TYPE_FILE; + f->name = strdup(fe.filename); + em->files = evas_list_append(em->files, f); + em->func(em->data, em, f->type, event, buf); + break; + case ECORE_FILE_EVENT_DELETED: + f = _ecore_file_monitor_fam_file_find(em, fe.filename); + if (f) + { + em->files = evas_list_remove(em->files, f); + em->func(em->data, em, f->type, event, buf); + free(f->name); + free(f); + } + break; + case ECORE_FILE_EVENT_CHANGED: + em->func(em->data, em, f->type, event, buf); + break; + } } +#endif } } return 1; } static Ecore_File * -_ecore_file_monitor_file_find(Ecore_File_Monitor *em, char *name) +_ecore_file_monitor_fam_file_find(Ecore_File_Monitor *em, char *name) { - Ecore_File_Monitor_Fam *emf; Evas_List *l; - emf = ECORE_FILE_MONITOR_FAM(em); - for (l = emf->files; l; l = l->next) + for (l = em->files; l; l = l->next) { Ecore_File *f; f = l->data; @@ -224,18 +264,31 @@ _ecore_file_monitor_file_find(Ecore_File_Monitor *em, char *name) } static Ecore_File_Event -_ecore_file_monitor_event_get(FAMCodes code) +_ecore_file_monitor_fam_event_get(FAMCodes code, int self, int is_dir) { switch (code) { case FAMCreated: - return ECORE_FILE_EVENT_CREATED; + if (self) + return ECORE_FILE_EVENT_NONE; + else if (is_dir) + return ECORE_FILE_EVENT_CREATED_DIRECTORY; + else + return ECORE_FILE_EVENT_CREATED_FILE; + break; case FAMDeleted: - return ECORE_FILE_EVENT_DELETED; + if (self) + return ECORE_FILE_EVENT_DELETED_SELF; + else if (is_dir) + return ECORE_FILE_EVENT_DELETED_DIRECTORY; + else + return ECORE_FILE_EVENT_DELETED_FILE; + break; case FAMChanged: - return ECORE_FILE_EVENT_CHANGED; + if (!is_dir) + return ECORE_FILE_EVENT_MODIFIED; + break; case FAMExists: - return ECORE_FILE_EVENT_EXISTS; case FAMStartExecuting: case FAMStopExecuting: case FAMMoved: diff --git a/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_inotify.c b/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_inotify.c index b3eea0b755..c15bca6a2c 100644 --- a/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_inotify.c +++ b/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_inotify.c @@ -5,81 +5,78 @@ /* * TODO: - * - Everything! */ #ifdef HAVE_INOTIFY +#include +#include +#include +#include +#include + typedef struct _Ecore_File_Monitor_Inotify Ecore_File_Monitor_Inotify; -typedef struct _Ecore_File Ecore_File; #define ECORE_FILE_MONITOR_INOTIFY(x) ((Ecore_File_Monitor_Inotify *)(x)) struct _Ecore_File_Monitor_Inotify { Ecore_File_Monitor monitor; - int fd; - Evas_List *files; - unsigned char deleted; + int wd; }; -struct _Ecore_File -{ - char *name; - int mtime; - Ecore_File_Type type; -}; +static Ecore_Fd_Handler *_fdh = NULL; +static Evas_List *_monitors = NULL; -static Ecore_Event_Handler *_eh; -static Evas_List *_monitors = NULL; -static int _lock = 0; - -static int _ecore_file_monitor_handler(void *data, int type, void *event); -static void _ecore_file_monitor_check(Ecore_File_Monitor *em); -static int _ecore_file_monitor_checking(Ecore_File_Monitor *em, char *path); +static int _ecore_file_monitor_inotify_handler(void *data, Ecore_Fd_Handler *fdh); +static Ecore_File_Monitor *_ecore_file_monitor_inotify_monitor_find(int wd); +static void _ecore_file_monitor_inotify_events(Ecore_File_Monitor *em, + char *file, int mask); int -ecore_file_monitor_init(void) +ecore_file_monitor_inotify_init(void) { - _eh = ecore_event_handler_add(ECORE_EVENT_SIGNAL_REALTIME, _ecore_file_monitor_handler, NULL); + int fd; + + fd = open("/dev/inotify", O_RDONLY); + if (fd < 0) + return 0; + + _fdh = ecore_main_fd_handler_add(fd, ECORE_FD_READ, _ecore_file_monitor_inotify_handler, + NULL, NULL, NULL); + if (!_fdh) + { + close(fd); + return 0; + } return 1; } int -ecore_file_monitor_shutdown(void) +ecore_file_monitor_inotify_shutdown(void) { - Evas_List *l; + int fd; - if (_eh) ecore_event_handler_del(_eh); - for (l = _monitors; l;) + if (_fdh) { - Ecore_File_Monitor *em; - - em = l->data; - l = l->next; - ecore_file_monitor_del(em); + fd = ecore_main_fd_handler_fd_get(_fdh); + ecore_main_fd_handler_del(_fdh); + close(fd); } - evas_list_free(_monitors); return 1; } Ecore_File_Monitor * -ecore_file_monitor_add(const char *path, - void (*func) (void *data, Ecore_File_Monitor *em, - Ecore_File_Type type, - Ecore_File_Event event, - const char *path), - void *data) +ecore_file_monitor_inotify_add(const char *path, + void (*func) (void *data, Ecore_File_Monitor *em, + Ecore_File_Event event, + const char *path), + void *data) { Ecore_File_Monitor *em; - Ecore_File_Monitor_Inotify *emd; int len; - if (!path) return NULL; - if (!func) return NULL; - - emd = calloc(1, sizeof(Ecore_File_Monitor_Inotify)); - em = ECORE_FILE_MONITOR(emd); + em = calloc(1, sizeof(Ecore_File_Monitor_Inotify)); if (!em) return NULL; em->func = func; @@ -88,62 +85,31 @@ ecore_file_monitor_add(const char *path, em->path = strdup(path); len = strlen(em->path); if (em->path[len - 1] == '/') - em->path[len - 1] = '\0'; + em->path[len - 1] = 0; if (ecore_file_exists(em->path)) { - em->type = ecore_file_is_dir(em->path) ? - ECORE_FILE_TYPE_DIRECTORY : - ECORE_FILE_TYPE_FILE; + struct inotify_watch_request request; - if (em->type == ECORE_FILE_TYPE_DIRECTORY) + request.name = em->path; + request.mask = IN_MODIFY| + IN_MOVED_FROM|IN_MOVED_TO| + IN_DELETE_SUBDIR|IN_DELETE_FILE| + IN_CREATE_SUBDIR|IN_CREATE_FILE| + IN_DELETE_SELF|IN_UNMOUNT; + ECORE_FILE_MONITOR_INOTIFY(em)->wd = ioctl(ecore_main_fd_handler_fd_get(_fdh), + INOTIFY_WATCH, &request); + if (ECORE_FILE_MONITOR_INOTIFY(em)->wd < 0) { - /* Check for subdirs */ - Evas_List *files, *l; - - files = ecore_file_ls(em->path); - for (l = files; l; l = l->next) - { - Ecore_File *f; - char *file; - char buf[PATH_MAX]; - - file = l->data; - 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); - f->type = ecore_file_is_dir(buf) ? - ECORE_FILE_TYPE_DIRECTORY : - ECORE_FILE_TYPE_FILE; - em->func(em->data, em, f->type, ECORE_FILE_EVENT_EXISTS, buf); - emd->files = evas_list_append(emd->files, f); - } - evas_list_free(files); - - emd->fd = open(em->path, O_RDONLY); - if (fcntl(emd->fd, F_SETSIG, SIGRTMIN + 1)) - printf("ERROR: F_SETSIG\n"); - if (fcntl(emd->fd, F_NOTIFY, DN_ACCESS|DN_MODIFY|DN_CREATE|DN_DELETE|DN_MULTISHOT)) - printf("ERROR: F_NOTIFY\n"); - } - else - { - /* TODO: We do not support monitoring files! */ - free(em); + printf("ioctl error\n"); + ecore_file_monitor_inotify_del(em); return NULL; } } else { - em->type = ECORE_FILE_TYPE_NONE; - em->func(em->data, em, em->type, ECORE_FILE_EVENT_DELETED, em->path); + ecore_file_monitor_inotify_del(em); + return NULL; } _monitors = evas_list_append(_monitors, em); @@ -152,165 +118,106 @@ ecore_file_monitor_add(const char *path, } void -ecore_file_monitor_del(Ecore_File_Monitor *em) +ecore_file_monitor_inotify_del(Ecore_File_Monitor *em) { - Ecore_File_Monitor_Inotify *emd; - Evas_List *l; - - emd = ECORE_FILE_MONITOR_INOTIFY(em); - if (_lock) - { - emd->deleted = 1; - return; - } - close(emd->fd); - /* Remove files */ - for (l = emd->files; l; l = l->next) - { - Ecore_File *f; - f = l->data; - free(f->name); - free(f); - } - evas_list_free(emd->files); + int fd; _monitors = evas_list_remove(_monitors, em); + + fd = ecore_main_fd_handler_fd_get(_fdh); + if (ECORE_FILE_MONITOR_INOTIFY(em)->wd) + ioctl(fd, INOTIFY_IGNORE, ECORE_FILE_MONITOR_INOTIFY(em)->wd); free(em->path); free(em); } static int -_ecore_file_monitor_handler(void *data, int type, void *event) +_ecore_file_monitor_inotify_handler(void *data, Ecore_Fd_Handler *fdh) { - Ecore_Event_Signal_Realtime *ev; - Evas_List *monitor; + Ecore_File_Monitor *em; + char buffer[16384]; + struct inotify_event *event; + int i = 0; + int event_size; + ssize_t size; - ev = event; - _lock = 1; - for (monitor = _monitors; monitor;) + size = read(ecore_main_fd_handler_fd_get(fdh), buffer, sizeof(buffer)); + while (i < size) { - Ecore_File_Monitor *em; - Ecore_File_Monitor_Inotify *emd; + event = (struct inotify_event *)&buffer[i]; + event_size = sizeof(struct inotify_event) + event->len; + i += event_size; - em = monitor->data; - emd = ECORE_FILE_MONITOR_INOTIFY(em); - monitor = monitor->next; + em = _ecore_file_monitor_inotify_monitor_find(event->wd); + if (!em) continue; - if (emd->fd == ev->data.si_fd) - _ecore_file_monitor_check(em); + _ecore_file_monitor_inotify_events(em, event->name, event->mask); } - _lock = 0; - for (monitor = _monitors; monitor;) - { - Ecore_File_Monitor *em; - Ecore_File_Monitor_Inotify *emd; - em = monitor->data; - emd = ECORE_FILE_MONITOR_INOTIFY(em); - monitor = monitor->next; - - if (emd->deleted) - ecore_file_monitor_del(em); - } return 1; } -#if 0 -static Ecore_File_Monitor_Request * -_ecore_file_monitor_request_find(Ecore_File_Monitor *em, char *path) +static Ecore_File_Monitor * +_ecore_file_monitor_inotify_monitor_find(int wd) { Evas_List *l; - for (l = em->requests; l; l = l->next) + for (l = _monitors; l; l = l->next) { - Ecore_File_Monitor_Request *er; + Ecore_File_Monitor *em; - er = l->data; - if (!strcmp(er->path, path)) - return er; + em = l->data; + if (ECORE_FILE_MONITOR_INOTIFY(em)->wd == wd) + return em; } return NULL; } -#endif static void -_ecore_file_monitor_check(Ecore_File_Monitor *em) +_ecore_file_monitor_inotify_events(Ecore_File_Monitor *em, char *file, int mask) { - Ecore_File_Monitor_Inotify *emd; - Evas_List *files, *l; + char buf[PATH_MAX]; + if (file) + snprintf(buf, sizeof(buf), "%s/%s", em->path, file); + else + strcpy(buf, em->path); - /* Check for changed files */ - emd = ECORE_FILE_MONITOR_INOTIFY(em); - for (l = emd->files; l;) + if (mask & IN_MODIFY) { - Ecore_File *f; - char buf[PATH_MAX]; - int mtime; - - 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) - { - em->func(em->data, em, f->type, ECORE_FILE_EVENT_DELETED, buf); - emd->files = evas_list_remove(emd->files, f); - free(f->name); - free(f); - } - else if (mtime > f->mtime) - em->func(em->data, em, f->type, ECORE_FILE_EVENT_CHANGED, buf); - f->mtime = mtime; + if (!ecore_file_is_dir(buf)) + em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, buf); } - - files = ecore_file_ls(em->path); - for (l = files; l; l = l->next) + if (mask & IN_MOVED_FROM) { - Ecore_File *f; - char *file; - char buf[PATH_MAX]; - - file = l->data; - if (_ecore_file_monitor_checking(em, file)) - { - free(file); - continue; - } - - 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); - f->type = ecore_file_is_dir(buf) ? - ECORE_FILE_TYPE_DIRECTORY : - ECORE_FILE_TYPE_FILE; - em->func(em->data, em, f->type, ECORE_FILE_EVENT_CREATED, buf); - emd->files = evas_list_append(emd->files, f); + printf("MOVE_FROM "); } -} - -static int -_ecore_file_monitor_checking(Ecore_File_Monitor *em, char *name) -{ - Ecore_File_Monitor_Inotify *emd; - Evas_List *l; - - emd = ECORE_FILE_MONITOR_INOTIFY(em); - for (l = emd->files; l; l = l->next) + if (mask & IN_MOVED_TO) { - Ecore_File *f; - - f = l->data; - if (!strcmp(f->name, name)) - return 1; + printf("MOVE_TO "); + } + if (mask & IN_DELETE_SUBDIR) + { + em->func(em->data, em, ECORE_FILE_EVENT_DELETED_DIRECTORY, buf); + } + if (mask & IN_DELETE_FILE) + { + em->func(em->data, em, ECORE_FILE_EVENT_DELETED_FILE, buf); + } + if (mask & IN_CREATE_SUBDIR) + { + em->func(em->data, em, ECORE_FILE_EVENT_CREATED_DIRECTORY, buf); + } + if (mask & IN_CREATE_FILE) + { + em->func(em->data, em, ECORE_FILE_EVENT_CREATED_FILE, buf); + } + if (mask & IN_DELETE_SELF) + { + em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path); + } + if (mask & IN_UNMOUNT) + { + printf("UNMOUNT "); } - - return 0; } #endif diff --git a/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c b/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c index 4872f250a8..c47830d45c 100644 --- a/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c +++ b/legacy/ecore/src/lib/ecore_file/ecore_file_monitor_poll.c @@ -14,13 +14,23 @@ * - Change poll time */ -typedef struct _Ecore_File Ecore_File; +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; +}; struct _Ecore_File { - char *name; - int mtime; - Ecore_File_Type type; + char *name; + int mtime; + unsigned char is_dir; }; #define ECORE_FILE_INTERVAL_MIN 1.0 @@ -32,18 +42,18 @@ static Ecore_Timer *_timer = NULL; static Evas_List *_monitors = NULL; static int _lock = 0; -static int _ecore_file_monitor_handler(void *data); -static void _ecore_file_monitor_check(Ecore_File_Monitor *em); -static int _ecore_file_monitor_checking(Ecore_File_Monitor *em, char *name); +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); int -ecore_file_monitor_init(void) +ecore_file_monitor_poll_init(void) { return 1; } int -ecore_file_monitor_shutdown(void) +ecore_file_monitor_poll_shutdown(void) { Evas_List *l; for (l = _monitors; l;) @@ -64,12 +74,11 @@ ecore_file_monitor_shutdown(void) } Ecore_File_Monitor * -ecore_file_monitor_add(const char *path, - void (*func) (void *data, Ecore_File_Monitor *em, - Ecore_File_Type type, - Ecore_File_Event event, - const char *path), - void *data) +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) { Ecore_File_Monitor *em; int len; @@ -77,11 +86,11 @@ ecore_file_monitor_add(const char *path, if (!path) return NULL; if (!func) return NULL; - em = calloc(1, sizeof(Ecore_File_Monitor)); + em = calloc(1, sizeof(Ecore_File_Monitor_Poll)); if (!em) return NULL; if (!_timer) - _timer = ecore_timer_add(_interval, _ecore_file_monitor_handler, NULL); + _timer = ecore_timer_add(_interval, _ecore_file_monitor_poll_handler, NULL); else ecore_timer_interval_set(_timer, ECORE_FILE_INTERVAL_MIN); @@ -93,15 +102,10 @@ ecore_file_monitor_add(const char *path, em->func = func; em->data = data; - em->mtime = ecore_file_mod_time(em->path); + ECORE_FILE_MONITOR_POLL(em)->mtime = ecore_file_mod_time(em->path); if (ecore_file_exists(em->path)) { - em->type = ecore_file_is_dir(em->path) ? - ECORE_FILE_TYPE_DIRECTORY : - ECORE_FILE_TYPE_FILE; - - em->func(em->data, em, em->type, ECORE_FILE_EVENT_EXISTS, em->path); - if (em->type == ECORE_FILE_TYPE_DIRECTORY) + if (ecore_file_is_dir(em->path)) { /* Check for subdirs */ Evas_List *files, *l; @@ -124,10 +128,7 @@ ecore_file_monitor_add(const char *path, snprintf(buf, sizeof(buf), "%s/%s", em->path, file); f->name = file; f->mtime = ecore_file_mod_time(buf); - f->type = ecore_file_is_dir(buf) ? - ECORE_FILE_TYPE_DIRECTORY : - ECORE_FILE_TYPE_FILE; - em->func(em->data, em, f->type, ECORE_FILE_EVENT_EXISTS, buf); + f->is_dir = ecore_file_is_dir(buf); em->files = evas_list_append(em->files, f); } evas_list_free(files); @@ -135,8 +136,8 @@ ecore_file_monitor_add(const char *path, } else { - em->type = ECORE_FILE_TYPE_NONE; - em->func(em->data, em, em->type, ECORE_FILE_EVENT_DELETED, em->path); + ecore_file_monitor_poll_del(em); + return NULL; } _monitors = evas_list_append(_monitors, em); @@ -145,13 +146,13 @@ ecore_file_monitor_add(const char *path, } void -ecore_file_monitor_del(Ecore_File_Monitor *em) +ecore_file_monitor_poll_del(Ecore_File_Monitor *em) { Evas_List *l; if (_lock) { - em->deleted = 1; + ECORE_FILE_MONITOR_POLL(em)->deleted = 1; return; } @@ -179,7 +180,7 @@ ecore_file_monitor_del(Ecore_File_Monitor *em) } static int -_ecore_file_monitor_handler(void *data __UNUSED__) +_ecore_file_monitor_poll_handler(void *data __UNUSED__) { Evas_List *monitor; @@ -191,7 +192,7 @@ _ecore_file_monitor_handler(void *data __UNUSED__) em = monitor->data; monitor = monitor->next; - _ecore_file_monitor_check(em); + _ecore_file_monitor_poll_check(em); } _lock = 0; if (_interval > ECORE_FILE_INTERVAL_MAX) @@ -204,179 +205,132 @@ _ecore_file_monitor_handler(void *data __UNUSED__) em = monitor->data; monitor = monitor->next; - if (em->deleted) + if (ECORE_FILE_MONITOR_POLL(em)->deleted) ecore_file_monitor_del(em); } return 1; } static void -_ecore_file_monitor_check(Ecore_File_Monitor *em) +_ecore_file_monitor_poll_check(Ecore_File_Monitor *em) { int mtime; + int is_dir; mtime = ecore_file_mod_time(em->path); - switch (em->type) + is_dir = ecore_file_is_dir(em->path); + if (mtime < ECORE_FILE_MONITOR_POLL(em)->mtime) { - case ECORE_FILE_TYPE_FILE: - if (mtime < em->mtime) - { - em->func(em->data, em, em->type, ECORE_FILE_EVENT_DELETED, em->path); - em->type = ECORE_FILE_TYPE_NONE; - _interval = ECORE_FILE_INTERVAL_MIN; - } - else if (mtime > em->mtime) - { - em->func(em->data, em, em->type, ECORE_FILE_EVENT_CHANGED, em->path); - _interval = ECORE_FILE_INTERVAL_MIN; - } - break; - case ECORE_FILE_TYPE_DIRECTORY: - if (mtime < em->mtime) - { - /* Deleted */ - Evas_List *l; + Evas_List *l; + Ecore_File_Event event; - /* Notify all files deleted */ - for (l = em->files; l;) - { - Ecore_File *f; - char buf[PATH_MAX]; + /* 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); - em->func(em->data, em, f->type, ECORE_FILE_EVENT_DELETED, buf); - free(f->name); - free(f); - } - em->files = evas_list_free(em->files); - em->func(em->data, em, em->type, ECORE_FILE_EVENT_DELETED, em->path); - em->type = ECORE_FILE_TYPE_NONE; - _interval = ECORE_FILE_INTERVAL_MIN; - } - else - { - Evas_List *l; - - /* Check for changed files */ - for (l = em->files; l;) - { - Ecore_File *f; - char buf[PATH_MAX]; - int mtime; - - 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) - { - em->func(em->data, em, f->type, ECORE_FILE_EVENT_DELETED, buf); - em->files = evas_list_remove(em->files, f); - free(f->name); - free(f); - _interval = ECORE_FILE_INTERVAL_MIN; - } - else if (mtime > f->mtime) - { - em->func(em->data, em, f->type, ECORE_FILE_EVENT_CHANGED, buf); - _interval = ECORE_FILE_INTERVAL_MIN; - } - f->mtime = mtime; - } - - /* Check for new files */ - if (em->mtime < mtime) - { - Evas_List *files; - - /* Files have been added or removed */ - files = ecore_file_ls(em->path); - for (l = files; l; l = l->next) - { - Ecore_File *f; - char *file; - char buf[PATH_MAX]; - - file = l->data; - if (_ecore_file_monitor_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->type = ecore_file_is_dir(buf) ? - ECORE_FILE_TYPE_DIRECTORY : - ECORE_FILE_TYPE_FILE; - em->func(em->data, em, f->type, ECORE_FILE_EVENT_CREATED, buf); - em->files = evas_list_append(em->files, f); - } - em->func(em->data, em, em->type, ECORE_FILE_EVENT_CHANGED, em->path); - _interval = ECORE_FILE_INTERVAL_MIN; - } - } - break; - case ECORE_FILE_TYPE_NONE: - if (mtime > em->mtime) - { - /* Something has been created! */ - em->type = ecore_file_is_dir(em->path) ? - ECORE_FILE_TYPE_DIRECTORY : - ECORE_FILE_TYPE_FILE; - - em->func(em->data, em, em->type, ECORE_FILE_EVENT_CREATED, em->path); - if (em->type == ECORE_FILE_TYPE_DIRECTORY) - { - /* Check for subdirs */ - Evas_List *files, *l; - - em->func(em->data, em, em->type, ECORE_FILE_EVENT_CREATED, em->path); - files = ecore_file_ls(em->path); - for (l = files; l; l = l->next) - { - Ecore_File *f; - char *file; - char buf[PATH_MAX]; - - file = l->data; - 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->type = ecore_file_is_dir(buf) ? - ECORE_FILE_TYPE_DIRECTORY : - ECORE_FILE_TYPE_FILE; - em->func(em->data, em, f->type, ECORE_FILE_EVENT_CREATED, buf); - em->files = evas_list_append(em->files, f); - } - evas_list_free(files); - } - _interval = ECORE_FILE_INTERVAL_MIN; - } - break; + 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; } - em->mtime = mtime; + else + { + 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) + { + Evas_List *files; + + /* Files have been added or removed */ + files = ecore_file_ls(em->path); + for (l = files; l; l = l->next) + { + Ecore_File *f; + char *file; + char buf[PATH_MAX]; + Ecore_File_Event event; + + file = l->data; + 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); + } + if (!ecore_file_is_dir(em->path)) + em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, em->path); + _interval = ECORE_FILE_INTERVAL_MIN; + } + } + ECORE_FILE_MONITOR_POLL(em)->mtime = mtime; } static int -_ecore_file_monitor_checking(Ecore_File_Monitor *em, char *name) +_ecore_file_monitor_poll_checking(Ecore_File_Monitor *em, char *name) { Evas_List *l; diff --git a/legacy/ecore/src/lib/ecore_file/ecore_file_private.h b/legacy/ecore/src/lib/ecore_file/ecore_file_private.h index c076bf2793..5559c743fb 100644 --- a/legacy/ecore/src/lib/ecore_file/ecore_file_private.h +++ b/legacy/ecore/src/lib/ecore_file/ecore_file_private.h @@ -4,12 +4,6 @@ #include #include -#include -#include -#include -#include -#include - #include "config.h" #include "Ecore.h" @@ -18,27 +12,52 @@ int ecore_file_monitor_init(void); int ecore_file_monitor_shutdown(void); +#define ECORE_FILE_MONITOR(x) ((Ecore_File_Monitor *)(x)) + struct _Ecore_File_Monitor { void (*func) (void *data, Ecore_File_Monitor *ecore_file_monitor, - Ecore_File_Type type, Ecore_File_Event event, const char *path); char *path; - Ecore_File_Type type; void *data; Evas_List *files; -#ifdef HAVE_POLL - int mtime; - unsigned char deleted; -#endif }; -/* -#define HAVE_POLL -#define HAVE_FAM -#define HAVE_DNOTIFY -#define HAVE_INOTIFY -*/ +#ifdef HAVE_INOTIFY +EAPI int ecore_file_monitor_inotify_init(void); +EAPI int ecore_file_monitor_inotify_shutdown(void); +EAPI Ecore_File_Monitor *ecore_file_monitor_inotify_add(const char *path, + void (*func) (void *data, + Ecore_File_Monitor *ecore_file_monitor, + Ecore_File_Event event, + const char *path), + void *data); +EAPI void ecore_file_monitor_inotify_del(Ecore_File_Monitor *ecore_file_monitor); +#endif + +#ifdef HAVE_FAM +EAPI int ecore_file_monitor_fam_init(void); +EAPI int ecore_file_monitor_fam_shutdown(void); +EAPI Ecore_File_Monitor *ecore_file_monitor_fam_add(const char *path, + void (*func) (void *data, + Ecore_File_Monitor *ecore_file_monitor, + Ecore_File_Event event, + const char *path), + void *data); +EAPI void ecore_file_monitor_fam_del(Ecore_File_Monitor *ecore_file_monitor); +#endif + +#ifdef HAVE_POLL +EAPI int ecore_file_monitor_poll_init(void); +EAPI int ecore_file_monitor_poll_shutdown(void); +EAPI Ecore_File_Monitor *ecore_file_monitor_poll_add(const char *path, + void (*func) (void *data, + Ecore_File_Monitor *ecore_file_monitor, + Ecore_File_Event event, + const char *path), + void *data); +EAPI void ecore_file_monitor_poll_del(Ecore_File_Monitor *ecore_file_monitor); +#endif