diff --git a/legacy/ecore/configure.in b/legacy/ecore/configure.in index c824a518c7..0cba2c5463 100644 --- a/legacy/ecore/configure.in +++ b/legacy/ecore/configure.in @@ -849,23 +849,26 @@ AC_ARG_ENABLE(ecore-file, ] ) -#AC_MSG_CHECKING(whether 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" -#] -#) +dnl We need to check if the right inotify version is accessible +AC_MSG_CHECKING(whether 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_TRY_COMPILE( + [#include ], + [struct inotify_watch_request request;request.fd = 0; request.mask = 0;], [ AC_DEFINE(HAVE_INOTIFY, 1, [ File monitoring with Inotify ]) use_inotify="yes" 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 e270e01a63..3a23283583 100644 --- a/legacy/ecore/src/lib/ecore_file/ecore_file_monitor.c +++ b/legacy/ecore/src/lib/ecore_file/ecore_file_monitor.c @@ -22,12 +22,11 @@ int ecore_file_monitor_init(void) { #ifdef HAVE_INOTIFY -#if 0 + printf("inotify\n"); 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; @@ -36,10 +35,12 @@ ecore_file_monitor_init(void) #endif #endif #ifdef HAVE_POLL + printf("poll\n"); monitor_type = ECORE_FILE_MONITOR_TYPE_POLL; if (ecore_file_monitor_poll_init()) return 1; #endif + printf("none\n"); monitor_type = ECORE_FILE_MONITOR_TYPE_NONE; return 0; } @@ -80,6 +81,7 @@ ecore_file_monitor_add(const char *path, return NULL; #ifdef HAVE_INOTIFY case ECORE_FILE_MONITOR_TYPE_INOTIFY: + printf("inotify add\n"); return ecore_file_monitor_inotify_add(path, func, data); #endif #ifdef HAVE_FAM @@ -88,6 +90,7 @@ ecore_file_monitor_add(const char *path, #endif #ifdef HAVE_POLL case ECORE_FILE_MONITOR_TYPE_POLL: + printf("poll add\n"); return ecore_file_monitor_poll_add(path, func, data); #endif } 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 1f8c34f06c..50879c2c73 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,16 +5,56 @@ /* * TODO: + * + * * Listen to these events: + * IN_ACCESS, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE, IN_OPEN + * */ #ifdef HAVE_INOTIFY +#include #include #include #include #include #include +/* These should go when it is standard that they are defined in userspace kernel headers */ +#if defined(__i386__) +# define __NR_inotify_init 291 +# define __NR_inotify_add_watch 292 +# define __NR_inotify_rm_watch 293 +#elif defined(__x86_64__) +# define __NR_inotify_init 253 +# define __NR_inotify_add_watch 254 +# define __NR_inotify_rm_watch 255 +#elif defined(__alpha__) +# define __NR_inotify_init 444 +# define __NR_inotify_add_watch 445 +# define __NR_inotify_rm_watch 446 +#elif defined(__ppc__) || defined(__powerpc__) || defined(__powerpc64__) +# define __NR_inotify_init 275 +# define __NR_inotify_add_watch 276 +# define __NR_inotify_rm_watch 277 +#elif defined(__sparc__) +# define __NR_inotify_init 151 +# define __NR_inotify_add_watch 152 +# define __NR_inotify_rm_watch 156 +#elif defined (__ia64__) +# define __NR_inotify_init 1277 +# define __NR_inotify_add_watch 1278 +# define __NR_inotify_rm_watch 1279 +#elif defined (__s390__) +# define __NR_inotify_init 284 +# define __NR_inotify_add_watch 285 +# define __NR_inotify_rm_watch 286 +#else +# warning "Unsupported architecture" +#endif + +#ifdef __NR_inotify_init + typedef struct _Ecore_File_Monitor_Inotify Ecore_File_Monitor_Inotify; #define ECORE_FILE_MONITOR_INOTIFY(x) ((Ecore_File_Monitor_Inotify *)(x)) @@ -33,15 +73,22 @@ 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); +static inline int inotify_init(void); +static inline int inotify_add_watch(int fd, const char *name, __u32 mask); +static inline int inotify_rm_watch(int fd, __u32 wd); + int ecore_file_monitor_inotify_init(void) { int fd; - fd = open("/dev/inotify", O_RDONLY); + /* Check if we can open /dev/inotify */ + printf("open\n"); + fd = inotify_init(); if (fd < 0) return 0; + printf("handler\n"); _fdh = ecore_main_fd_handler_add(fd, ECORE_FD_READ, _ecore_file_monitor_inotify_handler, NULL, NULL, NULL); if (!_fdh) @@ -87,6 +134,7 @@ ecore_file_monitor_inotify_add(const char *path, Ecore_File_Monitor *em; int len; + printf("Using inotify!\n"); em = calloc(1, sizeof(Ecore_File_Monitor_Inotify)); if (!em) return NULL; @@ -95,21 +143,19 @@ ecore_file_monitor_inotify_add(const char *path, em->path = strdup(path); len = strlen(em->path); - if (em->path[len - 1] == '/') + if (em->path[len - 1] == '/' && strcmp(em->path, "/")) em->path[len - 1] = 0; if (ecore_file_exists(em->path)) { - struct inotify_watch_request request; - - 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); + int mask; + mask = IN_MODIFY| + IN_MOVED_FROM|IN_MOVED_TO| + IN_DELETE|IN_CREATE| + IN_DELETE_SELF|IN_UNMOUNT; + ECORE_FILE_MONITOR_INOTIFY(em)->wd = inotify_add_watch(ecore_main_fd_handler_fd_get(_fdh), + em->path, + mask); if (ECORE_FILE_MONITOR_INOTIFY(em)->wd < 0) { printf("ioctl error\n"); @@ -137,7 +183,7 @@ ecore_file_monitor_inotify_del(Ecore_File_Monitor *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); + inotify_rm_watch(fd, ECORE_FILE_MONITOR_INOTIFY(em)->wd); free(em->path); free(em); } @@ -189,39 +235,46 @@ static void _ecore_file_monitor_inotify_events(Ecore_File_Monitor *em, char *file, int mask) { char buf[PATH_MAX]; + int isdir; + if (file) snprintf(buf, sizeof(buf), "%s/%s", em->path, file); else strcpy(buf, em->path); + isdir = mask & IN_ISDIR; if (mask & IN_MODIFY) { - if (!ecore_file_is_dir(buf)) + if (!isdir) em->func(em->data, em, ECORE_FILE_EVENT_MODIFIED, buf); } if (mask & IN_MOVED_FROM) { - printf("MOVE_FROM "); + if (isdir) + em->func(em->data, em, ECORE_FILE_EVENT_DELETED_DIRECTORY, buf); + else + em->func(em->data, em, ECORE_FILE_EVENT_DELETED_FILE, buf); } if (mask & IN_MOVED_TO) { - printf("MOVE_TO "); + if (isdir) + em->func(em->data, em, ECORE_FILE_EVENT_CREATED_DIRECTORY, buf); + else + em->func(em->data, em, ECORE_FILE_EVENT_CREATED_FILE, buf); } - if (mask & IN_DELETE_SUBDIR) + if (mask & IN_DELETE) { - em->func(em->data, em, ECORE_FILE_EVENT_DELETED_DIRECTORY, buf); + if (isdir) + em->func(em->data, em, ECORE_FILE_EVENT_DELETED_DIRECTORY, buf); + else + em->func(em->data, em, ECORE_FILE_EVENT_DELETED_FILE, buf); } - if (mask & IN_DELETE_FILE) + if (mask & IN_CREATE) { - 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 (isdir) + em->func(em->data, em, ECORE_FILE_EVENT_CREATED_DIRECTORY, buf); + else + em->func(em->data, em, ECORE_FILE_EVENT_CREATED_FILE, buf); } if (mask & IN_DELETE_SELF) { @@ -229,7 +282,27 @@ _ecore_file_monitor_inotify_events(Ecore_File_Monitor *em, char *file, int mask) } if (mask & IN_UNMOUNT) { - printf("UNMOUNT "); + /* We just call delete. The dir is gone... */ + em->func(em->data, em, ECORE_FILE_EVENT_DELETED_SELF, em->path); } } -#endif + +static inline int +inotify_init(void) +{ + return syscall(__NR_inotify_init); +} + +static inline int +inotify_add_watch(int fd, const char *name, __u32 mask) +{ + return syscall(__NR_inotify_add_watch, fd, name, mask); +} + +static inline int +inotify_rm_watch(int fd, __u32 wd) +{ + return syscall(__NR_inotify_rm_watch, fd, wd); +} +#endif /* __NR_inotify_init */ +#endif /* HAVE_INOTIFY */