summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2016-04-12 16:00:23 -0300
committerLauro Moura <lauromoura@expertisesolutions.com.br>2016-05-23 21:15:02 -0300
commite2dcc136b38c662a32ab9ab9d4d6fe6854399289 (patch)
tree2116d1ae33849a8eccbd2e6cbdee621b76dfba6d
parent1775fe18761127a7fa39a8098369c13fa5938ae6 (diff)
downloadefl-devs/felipealmeida/eio-eo.tar.gz
Adds Eo-based Eio api and moves the current Eio to legacy.devs/felipealmeida/eio-eo
The legacy Eio_File factory functions are replaced by an Eo object called Eo_Job that return promises wrapping the async file operations. With this commit, the legacy Eio callbacks are replaced by the following Eo/Promises counterparts : * Done_Cb -> Promise then success callback * Error_Cb -> Promise then error callback * Main_Cb -> Promise progress callback * Filter_Cb -> Job object event (more below) Events are used to deliver and get the filter data. To differentiate between the named and direct versions, they come in "filter,direct" and "filter,name" versions. Monitors were wrapped inside a new class Eo_Sentry. The user creates a sentry object and adds monitoring targets to it, listening to events on it. The sentry event info is composed of two strings. The source string is the path being monitored, i.e. the one passed to eio_sentry_add, and the trigger string is the path that actually triggered the event, e.g. a new file created in a monitored directory. Eina mmap and Eet-related functions are not (yet?) supported.
-rw-r--r--src/Makefile_Eio.am24
-rw-r--r--src/examples/eio/Makefile.am44
-rw-r--r--src/examples/eio/eio_job_ls.c79
-rw-r--r--src/examples/eio/eio_job_open.c80
-rw-r--r--src/examples/eio/eio_job_open_multi.c103
-rw-r--r--src/examples/eio/eio_sentry.c55
-rw-r--r--src/lib/eio/Eio.h1260
-rw-r--r--src/lib/eio/Eio_Eo.h13
-rw-r--r--src/lib/eio/Eio_Legacy.h1256
-rw-r--r--src/lib/eio/eio_job.c586
-rw-r--r--src/lib/eio/eio_job.eo152
-rw-r--r--src/lib/eio/eio_job_private.h12
-rw-r--r--src/lib/eio/eio_sentry.c166
-rw-r--r--src/lib/eio/eio_sentry.eo49
-rw-r--r--src/lib/eio/eio_sentry_private.h13
-rw-r--r--src/lib/eo/eina_types.eot8
-rw-r--r--src/tests/eio/eio_suite.c3
-rw-r--r--src/tests/eio/eio_suite.h3
-rw-r--r--src/tests/eio/eio_test_common.c89
-rw-r--r--src/tests/eio/eio_test_common.h16
-rw-r--r--src/tests/eio/eio_test_file.c72
-rw-r--r--src/tests/eio/eio_test_job.c287
-rw-r--r--src/tests/eio/eio_test_job_xattr.c204
-rw-r--r--src/tests/eio/eio_test_sentry.c755
-rw-r--r--src/tests/eio/eio_test_xattr.c17
25 files changed, 3993 insertions, 1353 deletions
diff --git a/src/Makefile_Eio.am b/src/Makefile_Eio.am
index 64b7972e81..f234f3e075 100644
--- a/src/Makefile_Eio.am
+++ b/src/Makefile_Eio.am
@@ -2,7 +2,9 @@
### Library
eio_eolian_files = \
- lib/eio/eio_model.eo
+ lib/eio/eio_model.eo \
+ lib/eio/eio_job.eo \
+ lib/eio/eio_sentry.eo
eio_eolian_h = $(eio_eolian_files:%.eo=%.eo.h)
eio_eolian_c = $(eio_eolian_files:%.eo=%.eo.c)
@@ -20,13 +22,19 @@ lib/eio/Makefile.in
installed_eiomainheadersdir = $(includedir)/eio-@VMAJ@
-dist_installed_eiomainheaders_DATA = lib/eio/Eio.h lib/eio/eio_inline_helper.x
+dist_installed_eiomainheaders_DATA = \
+lib/eio/Eio.h \
+lib/eio/Eio_Legacy.h \
+lib/eio/Eio_Eo.h \
+lib/eio/eio_inline_helper.x
nodist_installed_eiomainheaders_DATA = $(eio_eoolian_h)
lib_eio_libeio_la_SOURCES = \
lib/eio/eio_dir.c \
lib/eio/eio_eet.c \
lib/eio/eio_file.c \
+lib/eio/eio_job.c \
+lib/eio/eio_sentry.c \
lib/eio/eio_main.c \
lib/eio/eio_map.c \
lib/eio/eio_monitor.c \
@@ -62,13 +70,6 @@ if HAVE_NOTIFY_COCOA
lib_eio_libeio_la_LDFLAGS += -framework CoreServices
endif
-if HAVE_CXX11
-
-eio_eolian_cxx_hh = $(eio_eolian_files:%.eo=%.eo.hh)
-eio_eolian_cxx_impl = $(eio_eolian_files:%.eo=%.eo.impl.hh)
-
-endif
-
if EFL_ENABLE_TESTS
check_PROGRAMS += tests/eio/eio_suite
@@ -79,8 +80,13 @@ tests/eio/eio_suite.c \
tests/eio/eio_model_test_file.c \
tests/eio/eio_model_test_monitor_add.c \
tests/eio/eio_test_monitor.c \
+tests/eio/eio_test_sentry.c \
tests/eio/eio_test_file.c \
+tests/eio/eio_test_job.c \
+tests/eio/eio_test_job_xattr.c \
tests/eio/eio_test_xattr.c \
+tests/eio/eio_test_common.c \
+tests/eio/eio_test_common.h \
tests/eio/eio_suite.h
tests_eio_eio_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
diff --git a/src/examples/eio/Makefile.am b/src/examples/eio/Makefile.am
index 53b95fec48..4fccc70310 100644
--- a/src/examples/eio/Makefile.am
+++ b/src/examples/eio/Makefile.am
@@ -24,31 +24,53 @@ endif
EXTRA_PROGRAMS = \
eio_file_ls \
-eio_file_copy
+eio_file_copy \
+eio_job_open \
+eio_job_open_multi \
+eio_job_ls \
+eio_sentry
-eio_file_ls_SOURCES = eio_file_ls.c
-eio_file_ls_LDADD = \
+EIO_EXAMPLES_LDADD = \
$(top_builddir)/src/lib/eio/libeio.la \
$(top_builddir)/src/lib/eo/libeo.la \
$(top_builddir)/src/lib/ecore/libecore.la \
+$(top_builddir)/src/lib/efl/libefl.la \
$(top_builddir)/src/lib/eet/libeet.la \
$(top_builddir)/src/lib/emile/libemile.la \
$(top_builddir)/src/lib/eina/libeina.la \
@EIO_LDFLAGS@
+eio_file_ls_SOURCES = eio_file_ls.c
+eio_file_ls_LDADD = \
+$(EIO_EXAMPLES_LDADD)
+
eio_file_copy_SOURCES = eio_file_copy.c
eio_file_copy_LDADD = \
-$(top_builddir)/src/lib/eio/libeio.la \
-$(top_builddir)/src/lib/eo/libeo.la \
-$(top_builddir)/src/lib/ecore/libecore.la \
-$(top_builddir)/src/lib/eet/libeet.la \
-$(top_builddir)/src/lib/emile/libemile.la \
-$(top_builddir)/src/lib/eina/libeina.la \
-@EIO_LDFLAGS@
+$(EIO_EXAMPLES_LDADD)
+
+eio_job_open_SOURCES = eio_job_open.c
+eio_job_open_LDADD = \
+$(EIO_EXAMPLES_LDADD)
+
+eio_job_open_multi_SOURCES = eio_job_open_multi.c
+eio_job_open_multi_LDADD = \
+$(EIO_EXAMPLES_LDADD)
+
+eio_job_ls_SOURCES = eio_job_ls.c
+eio_job_ls_LDADD = \
+$(EIO_EXAMPLES_LDADD)
+
+eio_sentry_SOURCES = eio_sentry.c
+eio_sentry_LDADD = \
+$(EIO_EXAMPLES_LDADD)
SRCS = \
eio_file_ls.c \
-eio_file_copy.c
+eio_file_copy.c \
+eio_job_open.c \
+eio_job_open_multi.c \
+eio_job_ls.c \
+eio_sentry.c
DATA_FILES = Makefile.examples
diff --git a/src/examples/eio/eio_job_ls.c b/src/examples/eio/eio_job_ls.c
new file mode 100644
index 0000000000..354325e4f8
--- /dev/null
+++ b/src/examples/eio/eio_job_ls.c
@@ -0,0 +1,79 @@
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <Eina.h>
+#include <Eio.h>
+#include <Ecore.h>
+
+void done_cb(void *data, void *value EINA_UNUSED)
+{
+ Eio_Job *job = data;
+ printf("%s done listing files.\n", __FUNCTION__);
+ ecore_main_loop_quit();
+ eo_unref(job);
+}
+
+void error_cb(void *data, Eina_Error *error)
+{
+ Eio_Job *job = data;
+ EINA_SAFETY_ON_NULL_RETURN(error);
+ const char *msg = eina_error_msg_get(*error);
+ printf("%s error: %s\n", __FUNCTION__, msg);
+ ecore_main_loop_quit();
+
+ eo_unref(job);
+}
+
+void filter_cb(void *data, const Eo_Event *event)
+{
+ Eio_Filter_Name_Data *event_info = event->info;
+ static Eina_Bool should_filter = EINA_FALSE;
+
+ printf("Filtering file %s\n", event_info->file);
+
+ should_filter = !should_filter;
+ event_info->filter = should_filter;
+}
+
+// Progress used to be the "Eio_Main_Cb" family of callbacks in the legacy API.
+void progress_cb(void *data, const char *filename)
+{
+ EINA_SAFETY_ON_NULL_RETURN(filename);
+ printf("%s listing filename: %s\n", __FUNCTION__, filename);
+}
+
+void list_files(void *data)
+{
+ Eina_Promise *promise;
+ const char *path = data;
+
+ Eio_Job *job = eo_add(EIO_JOB_CLASS, NULL);
+ eo_event_callback_add(job, EIO_JOB_EVENT_FILTER_NAME, (Eo_Event_Cb)&filter_cb, NULL);
+ eio_job_file_ls(job, path, &promise);
+ eina_promise_progress_cb_add(promise, (Eina_Promise_Progress_Cb)&progress_cb, NULL, NULL);
+ eina_promise_then(promise, (Eina_Promise_Cb)&done_cb, (Eina_Promise_Error_Cb)&error_cb, job);
+}
+
+int main(int argc, char const *argv[])
+{
+ eio_init();
+ ecore_init();
+
+ const char *path = getenv("HOME");
+
+ if (argc > 1)
+ path = argv[1];
+
+ Ecore_Job *job = ecore_job_add(&list_files, path);
+
+ ecore_main_loop_begin();
+
+ ecore_shutdown();
+ eio_shutdown();
+ return 0;
+}
diff --git a/src/examples/eio/eio_job_open.c b/src/examples/eio/eio_job_open.c
new file mode 100644
index 0000000000..fb235c2e06
--- /dev/null
+++ b/src/examples/eio/eio_job_open.c
@@ -0,0 +1,80 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <Eina.h>
+#include <Eio.h>
+#include <Ecore.h>
+
+void error_cb(void *data, Eina_Error *error)
+{
+ EINA_SAFETY_ON_NULL_RETURN(error);
+ EINA_SAFETY_ON_NULL_RETURN(data);
+
+ const char *msg = eina_error_msg_get(*error);
+ EINA_LOG_ERR("error: %s", msg);
+
+ ecore_main_loop_quit();
+}
+
+void done_closing_cb(int *result EINA_UNUSED)
+{
+ printf("%s closed file.\n", __FUNCTION__);
+
+ ecore_main_loop_quit();
+}
+
+void closing_job(Eio_Job *job, Eina_File *file)
+{
+ Eina_Promise *promise = NULL;
+ printf("%s Will close the file...\n", __FUNCTION__);
+ eio_job_file_close(job, file, &promise);
+ eina_promise_then(promise, (Eina_Promise_Cb)&done_closing_cb, (Eina_Promise_Error_Cb)&error_cb, job);
+}
+
+void done_open_cb(void *data, Eina_File **file)
+{
+ EINA_SAFETY_ON_NULL_RETURN(data);
+ EINA_SAFETY_ON_NULL_RETURN(file);
+ EINA_SAFETY_ON_NULL_RETURN(*file);
+
+ Eio_Job *job = data;
+
+ const char *name = eina_file_filename_get(*file);
+ printf("%s opened file %s\n", __FUNCTION__, name);
+
+ closing_job(job, *file);
+}
+
+void open_file(const char *path)
+{
+ Eina_Promise *promise;
+
+ Eio_Job *job = eo_add(EIO_JOB_CLASS, NULL);
+ eio_job_file_open(job, path, EINA_FALSE, &promise);
+ eina_promise_then(promise, (Eina_Promise_Cb)&done_open_cb, (Eina_Promise_Error_Cb)&error_cb, job);
+
+ eo_unref(job);
+}
+
+int main(int argc, char const *argv[])
+{
+ eio_init();
+ ecore_init();
+
+ const char *path = getenv("HOME");
+
+ if (argc > 1)
+ path = argv[1];
+
+ open_file(path);
+
+ ecore_main_loop_begin();
+
+ ecore_shutdown();
+ eio_shutdown();
+ return 0;
+}
diff --git a/src/examples/eio/eio_job_open_multi.c b/src/examples/eio/eio_job_open_multi.c
new file mode 100644
index 0000000000..8082d4bfac
--- /dev/null
+++ b/src/examples/eio/eio_job_open_multi.c
@@ -0,0 +1,103 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <Eina.h>
+#include <Eio.h>
+#include <Ecore.h>
+
+void error_cb(void *data, Eina_Error *error)
+{
+ EINA_SAFETY_ON_NULL_RETURN(error);
+ EINA_SAFETY_ON_NULL_RETURN(data);
+
+ const char *msg = eina_error_msg_get(*error);
+ EINA_LOG_ERR("error: %s", msg);
+
+ Eio_Job *job = data;
+ eo_unref(job);
+
+ ecore_main_loop_quit();
+}
+
+void done_closing_cb(void *data, Eina_Iterator **result EINA_UNUSED)
+{
+ EINA_SAFETY_ON_NULL_RETURN(data);
+
+ printf("%s closed file.\n", __FUNCTION__);
+
+ Eio_Job *job = data;
+ eo_unref(job);
+
+ ecore_main_loop_quit();
+}
+
+void closing_job(Eio_Job *job, Eina_File *file1, Eina_File *file2)
+{
+ Eina_Promise *promise;
+ Eina_Promise *tasks[3] = {NULL, NULL, NULL};
+
+ printf("%s Closing files.\n", __FUNCTION__);
+ eio_job_file_close(job, file1, &tasks[0]);
+ eio_job_file_close(job, file2, &tasks[1]);
+ promise = eina_promise_all(eina_carray_iterator_new((void**)&tasks[0]));
+ eina_promise_then(promise, (Eina_Promise_Cb)&done_closing_cb, (Eina_Promise_Error_Cb)&error_cb, job);
+}
+
+void done_open_cb(void *data, Eina_Iterator **iterator)
+{
+ EINA_SAFETY_ON_NULL_RETURN(data);
+ EINA_SAFETY_ON_NULL_RETURN(iterator);
+ EINA_SAFETY_ON_NULL_RETURN(*iterator);
+ Eio_Job *job = data;
+
+ Eina_File **file = NULL;
+ Eina_File **files = calloc(sizeof(Eina_File*),2);
+ int i = 0;
+ while (eina_iterator_next(*iterator, (void**)&file))
+ {
+ files[i] = *file;
+ const char *name = eina_file_filename_get(*file);
+ printf("%s opened file %s\n", __FUNCTION__, name);
+ i++;
+ }
+ closing_job(job, files[0], files[1]);
+ free(files);
+}
+
+void open_file(const char *path, const char *path2)
+{
+ Eina_Promise *promise;
+ Eina_Promise *tasks[3] = {NULL, NULL, NULL};
+
+ Eio_Job *job = eo_add(EIO_JOB_CLASS, NULL);
+ eio_job_file_open(job, path, EINA_FALSE, &tasks[0]);
+ eio_job_file_open(job, path2, EINA_FALSE, &tasks[1]);
+ promise = eina_promise_all(eina_carray_iterator_new((void**)&tasks[0]));
+ eina_promise_then(promise, (Eina_Promise_Cb)&done_open_cb, (Eina_Promise_Error_Cb)&error_cb, job);
+}
+
+int main(int argc, char const *argv[])
+{
+ eio_init();
+ ecore_init();
+
+ const char *path = getenv("HOME");
+ const char *path2 = "./";
+
+ if (argc > 1)
+ path = argv[1];
+ if (argc > 2)
+ path2 = argv[2];
+
+ open_file(path, path2);
+
+ ecore_main_loop_begin();
+
+ ecore_shutdown();
+ eio_shutdown();
+ return 0;
+}
diff --git a/src/examples/eio/eio_sentry.c b/src/examples/eio/eio_sentry.c
new file mode 100644
index 0000000000..a6218a79e1
--- /dev/null
+++ b/src/examples/eio/eio_sentry.c
@@ -0,0 +1,55 @@
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <Eina.h>
+#include <Eio.h>
+#include <Ecore.h>
+
+Eina_Bool
+sentry_cb(void *data, const Eo_Event *event)
+{
+ Eio_Sentry_Event *event_info = event->info;
+
+ printf("Event on monitored path %s", event_info->source);
+ printf("Created file %s\n", event_info->trigger);
+
+ ecore_main_loop_quit();
+
+ return EINA_FALSE;
+}
+
+void
+monitor_stuff(void *data)
+{
+ const char *path = data;
+ Eio_Sentry *sentry = eo_add(EIO_SENTRY_CLASS, NULL);
+ eo_event_callback_add(sentry, EIO_SENTRY_EVENT_FILE_CREATED, (Eo_Event_Cb)&sentry_cb, NULL);
+
+ printf("Starting monitoring path %s\n", path);
+ eio_sentry_add(sentry, path);
+}
+
+int
+main(int argc, char const *argv[])
+{
+ eio_init();
+ ecore_init();
+
+ const char *path = getenv("HOME");
+
+ if (argc > 1)
+ path = argv[1];
+
+ Ecore_Job *job = ecore_job_add(&monitor_stuff, path);
+
+ ecore_main_loop_begin();
+
+ ecore_shutdown();
+ eio_shutdown();
+ return 0;
+}
diff --git a/src/lib/eio/Eio.h b/src/lib/eio/Eio.h
index 7ee29fe52a..16000f27ce 100644
--- a/src/lib/eio/Eio.h
+++ b/src/lib/eio/Eio.h
@@ -63,884 +63,12 @@
extern "C" {
#endif
-#define EIO_VERSION_MAJOR EFL_VERSION_MAJOR
-#define EIO_VERSION_MINOR EFL_VERSION_MINOR
-
- /**
- * @typedef Eio_Version
- * Represents the current version of EIO
- */
- typedef struct _Eio_Version
- {
- int major; /**< Major version number */
- int minor; /**< Minor version number */
- int micro; /**< Micro version number */
- int revision; /**< Revision number */
- } Eio_Version;
-
- EAPI extern Eio_Version *eio_version;
-
-/**
- * @file
- * @brief Eio asynchronous input/output library
- *
- * These routines are used for Eio.
- */
-
-/**
- * @page eio_main Eio
- *
- * @date 2012 (created)
- *
- * @section toc Table of Contents
- *
- * @li @ref eio_main_intro
- * @li @ref eio_main_compiling
- * @li @ref eio_main_next_steps
- * @li @ref eio_main_intro_example
- *
- * @section eio_main_intro Introduction
- *
- * The Eio library is a library that implements an API for asynchronous
- * input/output operation. Most operations are done in a separate thread
- * to prevent lock. See @ref Eio_Group. Some helper to work on data
- * received in Eio callback are also provided see @ref Eio_Helper.
- * It is also possible to work asynchronously on Eina_File with @ref Eio_Map
- * or on Eet_File with @ref Eio_Eet. It comes with way to manipulate
- * eXtended attribute asynchronous with @ref Eio_Xattr.
- *
- * This library is cross-platform and can be compiled and used on
- * Linux, BSD, Opensolaris and Windows (XP and CE). It is heavily
- * based on @ref Ecore_Main_Loop_Group.
- *
- * @section eio_main_compiling How to compile
- *
- * Eio is a library your application links to. The procedure for this is
- * very simple. You simply have to compile your application with the
- * appropriate compiler flags that the @c pkg-config script outputs. For
- * example:
- *
- * Compiling C or C++ files into object files:
- *
- * @verbatim
- gcc -c -o main.o main.c `pkg-config --cflags eio`
- @endverbatim
- *
- * Linking object files into a binary executable:
- *
- * @verbatim
- gcc -o my_application main.o `pkg-config --libs eio`
- @endverbatim
- *
- * See @ref pkgconfig
- *
- * @section eio_main_next_steps Next Steps
- *
- * After you understand what Eio is and installed it on your system
- * you should proceed understand the programming interface.
- *
- * Recommended reading:
- *
- * @li @ref Eio_Helper for common functions and library initialization.
- * @li @ref Eio_List for listing files asynchronous.
- * @li @ref Eio_Management for anyone who want to do a file manager (copy, rm, ...).
- * @li @ref Eio_Map to manipulate files asynchronously (mmap).
- * @li @ref Eio_Xattr to access file extended attributes (xattr).
- * @li @ref Eio_Monitor to monitor for file changes (inotify).
- * @li @ref Eio_Eet to access Eet files asynchronously.
- *
- * @section eio_main_intro_example Introductory Example
- *
- * @include eio_file_ls.c
- *
- * More examples can be found at @ref eio_examples.
- *
- */
-
-/**
- * @enum _Eio_File_Op
- *
- * @brief Input/Output operations on files.
- *
- * This enum represents the operations that can be done.
- */
-enum _Eio_File_Op
-{
- EIO_FILE_COPY, /**< I/O operation is about a specific file copy */
- EIO_FILE_MOVE, /**< I/O operation is about a specific file move */
- EIO_DIR_COPY, /**< I/O operation is about a specific directory copy */
- EIO_DIR_MOVE, /**< I/O operation is about a specific directory move */
- /** I/O operation is about destroying a path:
- * source will point to base path to be destroyed,
- * and dest will point to to path destroyed by this I/O
- */
- EIO_UNLINK,
- EIO_FILE_GETPWNAM, /**< I/O operation is trying to get uid from user name */
- EIO_FILE_GETGRNAM /**< I/O operation is trying to get gid from user name */
-};
-
-/**
- * @typedef Eio_File_Op
- * Input/Output operations on files.
- */
-typedef enum _Eio_File_Op Eio_File_Op;
-
-/**
- * @defgroup Eio_List Eio file listing API
- * @ingroup Eio
- *
- * @brief This functions helps list files asynchronously.
- *
- * This set of functions work on top of Eina_File and Ecore_Thread
- * to list files under various condition.
- *
- * @{
- */
-
-/**
- * @typedef Eio_File
- * Generic asynchronous I/O reference.
- */
-typedef struct _Eio_File Eio_File;
-
-/**
- * @typedef Eio_Progress
- * Progress information on a specific operation.
- */
-typedef struct _Eio_Progress Eio_Progress;
-
-typedef Eina_Bool (*Eio_Filter_Cb)(void *data, Eio_File *handler, const char *file);
-typedef void (*Eio_Main_Cb)(void *data, Eio_File *handler, const char *file);
-
-typedef Eina_Bool (*Eio_Filter_Direct_Cb)(void *data, Eio_File *handler, const Eina_File_Direct_Info *info);
-typedef Eina_Bool (*Eio_Filter_Dir_Cb)(void *data, Eio_File *handler, Eina_File_Direct_Info *info);
-typedef void (*Eio_Main_Direct_Cb)(void *data, Eio_File *handler, const Eina_File_Direct_Info *info);
-
-typedef void (*Eio_Stat_Cb)(void *data, Eio_File *handler, const Eina_Stat *stat);
-typedef void (*Eio_Progress_Cb)(void *data, Eio_File *handler, const Eio_Progress *info);
-
-typedef void (*Eio_Eet_Open_Cb)(void *data, Eio_File *handler, Eet_File *file);
-typedef void (*Eio_Open_Cb)(void *data, Eio_File *handler, Eina_File *file);
-typedef Eina_Bool (*Eio_Filter_Map_Cb)(void *data, Eio_File *handler, void *map, size_t length);
-typedef void (*Eio_Map_Cb)(void *data, Eio_File *handler, void *map, size_t length);
-
-typedef void (*Eio_Done_Data_Cb)(void *data, Eio_File *handler, const char *read_data, unsigned int size);
-typedef void (*Eio_Done_String_Cb)(void *data, Eio_File *handler, const char *xattr_string);
-typedef void (*Eio_Done_Double_Cb)(void *data, Eio_File *handler, double xattr_double);
-typedef void (*Eio_Done_Int_Cb)(void *data, Eio_File *handler, int i);
-
-typedef void (*Eio_Done_ERead_Cb)(void *data, Eio_File *handler, void *decoded);
-typedef void (*Eio_Done_Read_Cb)(void *data, Eio_File *handler, void *read_data, unsigned int size);
-typedef void (*Eio_Done_Cb)(void *data, Eio_File *handler);
-typedef void (*Eio_Error_Cb)(void *data, Eio_File *handler, int error);
-typedef void (*Eio_Eet_Error_Cb)(void *data, Eio_File *handler, Eet_Error err);
-
-/**
- * @struct _Eio_Progress
- * @brief Represents the current progress of the operation.
- */
-struct _Eio_Progress
-{
- Eio_File_Op op; /**< I/O type */
-
- long long current; /**< Current step in the I/O operation */
- long long max; /**< Number of total steps to complete this I/O */
- float percent; /**< Percent done for the I/O operation */
-
- const char *source; /**< source of the I/O operation */
- const char *dest; /**< target of the I/O operation */
-};
-
-/**
- * @brief List contents of a directory without locking your app.
- * @param dir The directory to list.
- * @param filter_cb Callback used to decide if the file will be passed to main_cb
- * @param main_cb Callback called for each listed file if it was not filtered.
- * @param done_cb Callback called when the ls operation is done.
- * @param error_cb Callback called when either the directory could not be opened or the operation has been canceled.
- * @param data Unmodified user data passed to callbacks
- * @return A reference to the I/O operation.
- *
- * This function is responsible for listing the content of a directory without blocking your application.
- * It's equivalent to the "ls" shell command. Every file will be passed to the
- * filter_cb, so it's your job to decide if you want to pass the file to the
- * main_cb or not. Return EINA_TRUE to pass it to the main_cb or EINA_FALSE to
- * ignore it. It runs eina_file_ls() in a separate thread using
- * ecore_thread_feedback_run().
- *
- * @see eina_file_ls()
- * @see ecore_thread_feedback_run()
- * @see eio_file_direct_ls()
- * @see eio_file_stat_ls()
- */
-EAPI Eio_File *eio_file_ls(const char *dir,
- Eio_Filter_Cb filter_cb,
- Eio_Main_Cb main_cb,
- Eio_Done_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief List contents of a directory without locking your app.
- * @param dir The directory to list.
- * @param filter_cb Callback used to decide if the file will be passed to main_cb
- * @param main_cb Callback called from the main loop for each accepted file (not filtered).
- * @param done_cb Callback called from the main loop after the contents of the directory has been listed.
- * @param error_cb Callback called from the main loop when either the directory could not be opened or the operation has been canceled.
- * @param data Unmodified user data passed to callbacks
- * @return A reference to the I/O operation.
- *
- * eio_file_direct_ls() runs eina_file_direct_ls() in a separate thread using
- * ecore_thread_feedback_run(). This prevents any blocking in your apps.
- * Every file will be passed to the filter_cb, so it's your job to decide if you
- * want to pass the file to the main_cb or not. Return EINA_TRUE to pass it to
- * the main_cb or EINA_FALSE to ignore it.
- *
- * @warning If readdir_r doesn't contain file type information, file type is
- * EINA_FILE_UNKNOWN.
- *
- * @note The iterator walks over '.' and '..' without returning them.
- * @note The difference between this function and eina_file_stat_ls() is that
- * it may not get the file type information however it is likely to be
- * faster.
- *
- * @see eio_file_stat_ls()
- * @see eina_file_direct_ls()
- * @see ecore_thread_feedback_run()
- */
-EAPI Eio_File *eio_file_direct_ls(const char *dir,
- Eio_Filter_Direct_Cb filter_cb,
- Eio_Main_Direct_Cb main_cb,
- Eio_Done_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief List content of a directory without locking your app.
- * @param dir The directory to list.
- * @param filter_cb Callback used to decide if the file will be passed to main_cb
- * @param main_cb Callback called from the main loop for each accepted file (not filtered).
- * @param done_cb Callback called from the main loop after the contents of the directory has been listed.
- * @param error_cb Callback called from the main loop when either the directory could not be opened or the operation has been canceled.
- * @param data Unmodified user data passed to callbacks
- * @return A reference to the I/O operation.
- *
- * Every file will be passed to the filter_cb, so it's your job to decide if you
- * want to pass the file to the main_cb or not. Return EINA_TRUE to pass it to
- * the main_cb or EINA_FALSE to ignore it. eio_file_stat_ls() run eina_file_stat_ls()
- * in a separate thread using ecore_thread_feedback_run().
- *
- * @note The iterator walks over '.' and '..' without returning them.
- * @note The difference between this function and eio_file_direct_ls() is that
- * it guarantees the file type information to be correct by incurring a
- * possible performance penalty.
- *
- * @see eio_file_stat_ls()
- * @see eina_file_stat_ls()
- * @see ecore_thread_feedback_run()
- */
-EAPI Eio_File *eio_file_stat_ls(const char *dir,
- Eio_Filter_Direct_Cb filter_cb,
- Eio_Main_Direct_Cb main_cb,
- Eio_Done_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief List the content of a directory and all its sub-content asynchronously
- * @param dir The directory to list.
- * @param filter_cb Callback used to decide if the file will be passed to main_cb
- * @param main_cb Callback called from the main loop for each accepted file (not filtered).
- * @param done_cb Callback called from the main loop after the contents of the directory has been listed.
- * @param error_cb Callback called from the main loop when either the directory could not be opened or the operation has been canceled.
- * @param data Unmodified user data passed to callbacks
- * @return A reference to the I/O operation.
- *
- * eio_dir_stat_ls() runs eina_file_stat_ls() recursively in a separate thread using
- * ecore_thread_feedback_run(). This prevents any blocking in your apps.
- * Every file will be passed to the
- * filter_cb, so it's your job to decide if you want to pass the file to the
- * main_cb or not. Return EINA_TRUE to pass it to the main_cb or EINA_FALSE to
- * ignore it.
- *
- * @see eio_file_stat_ls()
- * @see eio_dir_direct_ls()
- * @see eina_file_stat_ls()
- * @see ecore_thread_feedback_run()
- */
-EAPI Eio_File *eio_dir_stat_ls(const char *dir,
- Eio_Filter_Direct_Cb filter_cb,
- Eio_Main_Direct_Cb main_cb,
- Eio_Done_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief List the content of a directory and all its sub-content asynchronously
- * @param dir The directory to list.
- * @param filter_cb Callback used to decide if the file will be passed to main_cb
- * @param main_cb Callback called from the main loop for each accepted file (not filtered).
- * @param done_cb Callback called from the main loop after the contents of the directory has been listed.
- * @param error_cb Callback called from the main loop when either the directory could not be opened or the operation has been canceled.
- * @param data Unmodified user data passed to callbacks
- * @return A reference to the I/O operation.
- *
- * eio_dir_direct_ls() runs eina_file_direct_ls() recursively in a separate thread using
- * ecore_thread_feedback_run(). This prevents any blocking in your apps.
- * Every file will be passed to the filter_cb, so it's your job to decide if you
- * want to pass the file to the main_cb or not. Return EINA_TRUE to pass it to
- * the main_cb or EINA_FALSE to ignore it.
- *
- * @see eio_file_direct_ls()
- * @see eio_dir_stat_ls()
- * @see eina_file_direct_ls()
- * @see ecore_thread_feedback_run()
- */
-EAPI Eio_File *eio_dir_direct_ls(const char *dir,
- Eio_Filter_Dir_Cb filter_cb,
- Eio_Main_Direct_Cb main_cb,
- Eio_Done_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief Stat a file/directory.
- * @param path The path to stat.
- * @param done_cb Callback called from the main loop when stat was successfully called.
- * @param error_cb Callback called from the main loop when stat failed or has been canceled.
- * @param data Unmodified user data passed to callbacks
- * @return A reference to the I/O operation.
- *
- * eio_file_direct_stat calls stat in another thread. This prevents any blocking in your apps.
- */
-EAPI Eio_File *eio_file_direct_stat(const char *path,
- Eio_Stat_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @}
- */
-
-/**
- * @defgroup Eio_Management Eio file management API.
- *
- * @brief A set of function to manage file asynchronously.
- *
- * The function provided by this API are the one useful for any
- * file manager. Like moving or copying a file, unlinking it, changing
- * it's access right, ...
- *
- * @{
- */
-
-/**
- * @brief Change rights of a path.
- * @param path The directory path to change access rights.
- * @param mode The permission to set, follow (mode & ~umask & 0777).
- * @param done_cb Callback called when the operation is completed.
- * @param error_cb Callback called from if something goes wrong.
- * @param data Unmodified user data passed to callbacks.
- * @return A reference to the I/O operation.
- *
- * Set a new permission of a path changing it to the mode passed as argument.
- * It's equivalent to the chmod command.
- */
-EAPI Eio_File *eio_file_chmod(const char *path,
- mode_t mode,
- Eio_Done_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief Change owner of a path.
- * @param path The directory path to change owner.
- * @param user The new user to set (can be NULL).
- * @param group The new group to set (can be NULL).
- * @param done_cb Callback called when the operation is completed.
- * @param error_cb Callback called from if something goes wrong.
- * @param data Unmodified user data passed to callbacks
- * @return A reference to the I/O operation.
- *
- * This function will change the owner of a path, setting it to the user and
- * group passed as argument. It's equivalent to the chown shell command.
- */
-EAPI Eio_File *eio_file_chown(const char *path,
- const char *user,
- const char *group,
- Eio_Done_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief Unlink a file/directory.
- * @param path The path to unlink.
- * @param done_cb Callback called when the operation is completed.
- * @param error_cb Callback called from if something goes wrong.
- * @param data Unmodified user data passed to callbacks.
- * @return A reference to the I/O operation.
- *
- * This function will erase a file.
- */
-EAPI Eio_File *eio_file_unlink(const char *path,
- Eio_Done_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief Create a new directory.
- * @param path The directory path to create.
- * @param mode The permission to set, follow (mode & ~umask & 0777).
- * @param done_cb Callback called when the operation is completed.
- * @param error_cb Callback called from if something goes wrong.
- * @param data Unmodified user data passed to callbacks
- * @return A reference to the I/O operation.
- *
- * Creates a new directory using the mode provided.
- */
-EAPI Eio_File *eio_file_mkdir(const char *path,
- mode_t mode,
- Eio_Done_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief Move a file asynchronously
- * @param source Should be the name of the file to move the data from.
- * @param dest Should be the name of the file to move the data to.
- * @param progress_cb Callback called to know the progress of the move.
- * @param done_cb Callback called when the move is done.
- * @param error_cb Callback called when something goes wrong.
- * @param data Unmodified user data passed to callbacks
- * @return A reference to the I/O operation.
- *
- * @return an Eio_File pointer, handler to the move operation, can be used to cancel the operation
- *
- * This function will copy a file from source to dest. It will try to use splice
- * if possible, if not it will fallback to mmap/write. It will try to preserve
- * access rights, but not user/group identification.
- */
-EAPI Eio_File *eio_file_move(const char *source,
- const char *dest,
- Eio_Progress_Cb progress_cb,
- Eio_Done_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief Copy a file asynchronously
- * @param source Should be the name of the file to copy the data from.
- * @param dest Should be the name of the file to copy the data to.
- * @param progress_cb Callback called to know the progress of the copy.
- * @param done_cb Callback called when the copy is done.
- * @param error_cb Callback called when something goes wrong.
- * @param data Unmodified user data passed to callbacks
- *
- * @return an Eio_File pointer, handler to the copy operation, can be used to cancel the operation
- *
- * This function will copy a file from source to dest. It will try to use splice
- * if possible, if not it will fallback to mmap/write. It will try to preserve
- * access rights, but not user/group identification.
- */
-EAPI Eio_File *eio_file_copy(const char *source,
- const char *dest,
- Eio_Progress_Cb progress_cb,
- Eio_Done_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief Move a directory and its content asynchronously
- * @param source Should be the name of the directory to copy the data from.
- * @param dest Should be the name of the directory to copy the data to.
- * @param filter_cb Possible to deny the move of some files/directories.
- * @param progress_cb Callback called to know the progress of the copy.
- * @param done_cb Callback called when the copy is done.
- * @param error_cb Callback called when something goes wrong.
- * @param data Unmodified user data passed to callbacks
- * @return A reference to the I/O operation.
- *
- * @return an Eio_File pointer, handler to the move operation, can be used to cancel the operation
- *
- * This function will move a directory and all its content from source to dest.
- * It will try first to rename the directory, if not it will try to use splice
- * if possible, if not it will fallback to mmap/write.
- * It will try to preserve access rights, but not user/group identity.
- * Every file will be passed to the filter_cb, so it's your job to decide if you
- * want to pass the file to the main_cb or not. Return EINA_TRUE to pass it to
- * the main_cb or EINA_FALSE to ignore it.
- *
- * @note if a rename occurs, the filter callback will not be called.
- */
-EAPI Eio_File *eio_dir_move(const char *source,
- const char *dest,
- Eio_Filter_Direct_Cb filter_cb,
- Eio_Progress_Cb progress_cb,
- Eio_Done_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief Copy a directory and its content asynchronously
- * @param source Should be the name of the directory to copy the data from.
- * @param dest Should be the name of the directory to copy the data to.
- * @param filter_cb Possible to deny the move of some files/directories.
- * @param progress_cb Callback called to know the progress of the copy.
- * @param done_cb Callback called when the copy is done.
- * @param error_cb Callback called when something goes wrong.
- * @param data Unmodified user data passed to callbacks
- * @return A reference to the I/O operation.
- *
- * @return an Eio_File pointer, handler to the copy operation, can be used to cancel the operation
- *
- * This function will copy a directory and all its content from source to dest.
- * It will try to use splice if possible, if not it will fallback to mmap/write.
- * It will try to preserve access rights, but not user/group identity.
- * Every file will be passed to the filter_cb, so it's your job to decide if you
- * want to pass the file to the main_cb or not. Return EINA_TRUE to pass it to
- * the main_cb or EINA_FALSE to ignore it.
- */
-EAPI Eio_File *eio_dir_copy(const char *source,
- const char *dest,
- Eio_Filter_Direct_Cb filter_cb,
- Eio_Progress_Cb progress_cb,
- Eio_Done_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief Remove a directory and its content asynchronously
- * @param path Should be the name of the directory to destroy.
- * @param filter_cb Possible to deny the move of some files/directories.
- * @param progress_cb Callback called to know the progress of the copy.
- * @param done_cb Callback called when the copy is done.
- * @param error_cb Callback called when something goes wrong.
- * @param data Unmodified user data passed to callbacks
- * @return A reference to the I/O operation.
- *
- * @return an Eio_File pointer, handler to the unlink operation, can be used to cancel the operation
- *
- * This function will remove a directory and all its content.
- * Every file will be passed to the filter_cb, so it's your job to decide if you
- * want to pass the file to the main_cb or not. Return EINA_TRUE to pass it to
- * the main_cb or EINA_FALSE to ignore it.
- */
-EAPI Eio_File *eio_dir_unlink(const char *path,
- Eio_Filter_Direct_Cb filter_cb,
- Eio_Progress_Cb progress_cb,
- Eio_Done_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-/**
- * @}
- */
-
-/**
- * @defgroup Eio_Xattr Eio manipulation of eXtended attribute.
- * @ingroup Eio
- *
- * @brief A set of function to manipulate data associated with a specific file
- *
- * The functions provided by this API are responsible to manage Extended
- * attribute files. Like file authors, character encoding, checksum, etc.
- * @{
- */
-
-/**
- * @brief Asynchronously list all eXtended attribute
- * @param path The path to get the eXtended attribute from.
- * @param filter_cb Callback called in the thread to validate the eXtended attribute.
- * @param main_cb Callback called in the main loop for each accepted eXtended attribute.
- * @param done_cb Callback called in the main loop when the all the eXtended attribute have been listed.
- * @param error_cb Callback called in the main loop when something goes wrong during the listing of the eXtended attribute.
- * @param data Unmodified user data passed to callbacks
- * @return A reference to the I/O operation.
- */
-EAPI Eio_File *eio_file_xattr(const char *path,
- Eio_Filter_Cb filter_cb,
- Eio_Main_Cb main_cb,
- Eio_Done_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief Define an extented attribute on a file/directory.
- * @param path The path to set the attribute on.
- * @param attribute The name of the attribute to define.
- * @param xattr_int The value to link the attribute with.
- * @param flags Whether to insert, replace or create the attribute.
- * @param done_cb The callback called from the main loop when setxattr succeeded.
- * @param error_cb The callback called from the main loop when setxattr failed.
- * @param data Unmodified user data passed to callbacks
- * @return A reference to the I/O operation.
- *
- * eio_file_xattr_int_set calls eina_xattr_int_set from another thread. This prevents blocking in your apps. If
- * the writing succeeded, the done_cb will be called even if a cancel was requested, but came too late.
- */
-EAPI Eio_File *eio_file_xattr_int_set(const char *path,
- const char *attribute,
- int xattr_int,
- Eina_Xattr_Flags flags,
- Eio_Done_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief Define an extented attribute on a file/directory.
- * @param path The path to set the attribute on.
- * @param attribute The name of the attribute to define.
- * @param xattr_double The value to link the attribute with.
- * @param flags Whether to insert, replace or create the attribute.
- * @param done_cb The callback called from the main loop when setxattr succeeded.
- * @param error_cb The callback called from the main loop when setxattr failed.
- * @param data Unmodified user data passed to callbacks
- * @return A reference to the I/O operation.
- *
- * eio_file_xattr_double_set calls eina_xattr_double_set from another thread. This prevents blocking in your apps. If
- * the writing succeeded, the done_cb will be called even if a cancel was requested, but came too late.
- */
-EAPI Eio_File *eio_file_xattr_double_set(const char *path,
- const char *attribute,
- double xattr_double,
- Eina_Xattr_Flags flags,
- Eio_Done_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-/**
- * @brief Define a string extented attribute on a file/directory.
- * @param path The path to set the attribute on.
- * @param attribute The name of the attribute to define.
- * @param xattr_string The string to link the attribute with.
- * @param flags Whether to insert, replace or create the attribute.
- * @param done_cb The callback called from the main loop when setxattr succeeded.
- * @param error_cb The callback called from the main loop when setxattr failed.
- * @param data Unmodified user data passed to callbacks
- * @return A reference to the I/O operation.
- *
- * eio_file_xattr_string_set calls eina_xattr_string_set from another thread. This prevents blocking in your apps. If
- * the writing succeeded, the done_cb will be called even if a cancel was requested, but came too late.
- */
-EAPI Eio_File *eio_file_xattr_string_set(const char *path,
- const char *attribute,
- const char *xattr_string,
- Eina_Xattr_Flags flags,
- Eio_Done_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-/**
- * @brief Define an extented attribute on a file/directory.
- * @param path The path to set the attribute on.
- * @param attribute The name of the attribute to define.
- * @param xattr_data The data to link the attribute with.
- * @param xattr_size The size of the data to set.
- * @param flags Whether to insert, replace or create the attribute.
- * @param done_cb The callback called from the main loop when setxattr succeeded.
- * @param error_cb The callback called from the main loop when setxattr failed.
- * @param data Unmodified user data passed to callbacks
- * @return A reference to the I/O operation.
- *
- * eio_file_xattr_set calls setxattr from another thread. This prevents blocking in your apps. If
- * the writing succeeded, the done_cb will be called even if a cancel was requested, but came too late.
- */
-EAPI Eio_File *eio_file_xattr_set(const char *path,
- const char *attribute,
- const char *xattr_data,
- unsigned int xattr_size,
- Eina_Xattr_Flags flags,
- Eio_Done_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief Retrieve the extended attribute of a file/directory.
- * @param path The path to retrieve the extended attribute from.
- * @param attribute The name of the attribute to retrieve.
- * @param done_cb Callback called from the main loop when getxattr succeeded.
- * @param error_cb Callback called from the main loop when getxattr failed or has been canceled.
- * @param data Unmodified user data passed to callbacks
- * @return A reference to the I/O operation.
- *
- * eio_file_xattr_get calls getxattr from another thread. This prevents blocking in your apps.
- */
-EAPI Eio_File *eio_file_xattr_get(const char *path,
- const char *attribute,
- Eio_Done_Data_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-/**
- * @brief Retrieve a extended attribute of a file/directory.
- * @param path The path to retrieve the extended attribute from.
- * @param attribute The name of the attribute to retrieve.
- * @param done_cb Callback called from the main loop when getxattr succeeded.
- * @param error_cb Callback called from the main loop when getxattr failed or has been canceled.
- * @param data Unmodified user data passed to callbacks
- * @return A reference to the I/O operation.
- *
- * eio_file_xattr_int_get calls eina_xattr_int_get from another thread. This prevents blocking in your apps.
- */
-EAPI Eio_File *eio_file_xattr_int_get(const char *path,
- const char *attribute,
- Eio_Done_Int_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-/**
- * @brief Retrieve a extended attribute of a file/directory.
- * @param path The path to retrieve the extended attribute from.
- * @param attribute The name of the attribute to retrieve.
- * @param done_cb Callback called from the main loop when getxattr succeeded.
- * @param error_cb Callback called from the main loop when getxattr failed or has been canceled.
- * @param data Unmodified user data passed to callbacks
- * @return A reference to the I/O operation.
- *
- * eio_file_xattr_double_get calls eina_xattr_double_get from another thread. This prevents blocking in your apps.
- */
-EAPI Eio_File *eio_file_xattr_double_get(const char *path,
- const char *attribute,
- Eio_Done_Double_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-/**
- * @brief Retrieve a string extended attribute of a file/directory.
- * @param path The path to retrieve the extended attribute from.
- * @param attribute The name of the attribute to retrieve.
- * @param done_cb Callback called from the main loop when getxattr succeeded.
- * @param error_cb Callback called from the main loop when getxattr failed or has been canceled.
- * @param data Unmodified user data passed to callbacks
- * @return A reference to the I/O operation.
- *
- * eio_file_xattr_string_get calls eina_xattr_string_get from another thread. This prevents blocking in your apps.
- */
-EAPI Eio_File *eio_file_xattr_string_get(const char *path,
- const char *attribute,
- Eio_Done_String_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @}
- */
-
-/**
- * @defgroup Eio_Helper Eio Reference helper API
- * @ingroup Eio
- *
- * @brief This are helper provided around core Eio API.
- *
- * This set of functions do provide helper to work around data
- * provided by Eio without the need to look at system header.
- *
- * @{
- */
-
-
-/**
- * @brief Initialize eio and all its required submodule.
- * @return the current number of eio users.
- */
-EAPI int eio_init(void);
-
-/**
- * @brief Shutdown eio and all its submodule if possible.
- * @return the number of pending users of eio.
- */
-EAPI int eio_shutdown(void);
-
-/**
- * @brief Set the limit to the maximum amount of memory used
- * @param limit The actual limit to set.
- *
- * Eio work by burst, allocating memory in a thread and moving it
- * back to the main loop. This result in quite some huge memory
- * usage if the main loop is to slow to cope with the speed of the
- * thread. By setting this limit, the thread will block until
- * enough memory has been freed to be below the limit again.
- *
- * By default no limit is set and any value < 0 will mean no limit.
- *
- * @note You should give at least a reasonable amount of memory or
- * the thread might stall.
- * @since 1.10
- */
-EAPI void eio_memory_burst_limit_set(size_t limit);
-
-/**
- * @brief Get the actual limit to the maximum amount of memory used
- * @return The current limit being set.
- *
- * @since 1.10
- * @see eio_memory_burst_limit_set
- */
-EAPI size_t eio_memory_burst_limit_get(void);
-
-/**
- * @brief Return the container during EIO operation
- * @param ls The asynchronous I/O operation to retrieve container from.
- * @return NULL if not available, a DIRP if it is.
- *
- * This is only available and make sense in the thread callback, not in
- * the mainloop.
- */
-EAPI void *eio_file_container_get(Eio_File *ls);
-
-/**
- * @brief Cancel any Eio_File.
- * @param ls The asynchronous I/O operation to cancel.
- * @return EINA_FALSE if the destruction is delayed, EINA_TRUE if it's done.
- *
- * This will cancel any kind of I/O operation and cleanup the mess. This means
- * that it could take time to cancel an I/O.
- */
-EAPI Eina_Bool eio_file_cancel(Eio_File *ls);
-
-/**
- * @brief Check if an Eio_File operation has been cancelled.
- * @param ls The asynchronous I/O operation to check.
- * @return EINA_TRUE if it was canceled, EINA_FALSE other wise.
- *
- * In case of an error it also return EINA_TRUE.
- */
-EAPI Eina_Bool eio_file_check(Eio_File *ls);
-
-/**
- * @brief Associate data with the current filtered file.
- * @param ls The Eio_File ls request currently calling the filter callback.
- * @param key The key to associate data to.
- * @param data The data to associate the data to.
- * @param free_cb Optionally a function to call to free the associated data,
- * @p data is passed as the callback data parameter. If no @p free_cb is provided
- * the user @p data remains untouched.
- * @return EINA_TRUE if insertion was fine.
- *
- * This function can only be safely called from within the filter callback.
- * If you don't need to copy the key around you can use @ref eio_file_associate_direct_add
- */
-EAPI Eina_Bool eio_file_associate_add(Eio_File *ls,
- const char *key,
- const void *data, Eina_Free_Cb free_cb);
-
-/**
- * @brief Associate data with the current filtered file.
- * @param ls The Eio_File ls request currently calling the filter callback.
- * @param key The key to associate data to (will not be copied, and the pointer will not be used as long as the file is not notified).
- * @param data The data to associate the data to.
- * @param free_cb The function to call to free the associated data, @p free_cb will be called if not specified.
- * @return EINA_TRUE if insertion was fine.
- *
- * This function can only be safely called from within the filter callback.
- * If you need eio to make a proper copy of the @p key to be safe use
- * @ref eio_file_associate_add instead.
- */
-EAPI Eina_Bool eio_file_associate_direct_add(Eio_File *ls,
- const char *key,
- const void *data, Eina_Free_Cb free_cb);
-
-/**
- * @brief Get the data associated during the filter callback inside the main loop
- * @param ls The Eio_File ls request currently calling the notify callback.
- * @param key The key pointing to the data to retrieve.
- * @return the data associated with the key or @p NULL if not found.
- */
-EAPI void *eio_file_associate_find(Eio_File *ls, const char *key);
+#ifndef EFL_NOLEGACY_API_SUPPORT
+#include "Eio_Legacy.h"
+#endif
+#ifdef EFL_EO_API_SUPPORT
+#include "Eio_Eo.h"
+#endif
/**
* @brief get access time from a Eina_Stat
@@ -982,381 +110,11 @@ static inline Eina_Bool eio_file_is_dir(const Eina_Stat *stat);
*/
static inline Eina_Bool eio_file_is_lnk(const Eina_Stat *stat);
-/**
- * @}
- */
-
-/**
- *
- */
-
-/**
- * @defgroup Eio_Map Manipulate an Eina_File asynchronously
- * @ingroup Eio
- *
- * @brief This function helps when manipulating a file asynchronously.
- *
- * These set of functions work on top of Eina_File and Ecore_Thread to
- * do basic operations on a file, like opening, closing and mapping a file to
- * memory.
- * @{
- */
-
-/**
- * @brief Asynchronously open a file.
- * @param name The file to open.
- * @param shared If it's a shared memory file.
- * @param open_cb Callback called in the main loop when the file has been successfully opened.
- * @param error_cb Callback called in the main loop when the file couldn't be opened.
- * @param data Unmodified user data passed to callbacks
- * @return Pointer to the file if successful or NULL otherwise.
- *
- */
-EAPI Eio_File *eio_file_open(const char *name, Eina_Bool shared,
- Eio_Open_Cb open_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief Asynchronously close a file.
- * @param f The file to close.
- * @param done_cb Callback called in the main loop when the file has been successfully closed.
- * @param error_cb Callback called in the main loop when the file couldn't be closed.
- * @param data Unmodified user data passed to callbacks
- * @return Pointer to the file if successful or NULL otherwise.
- */
-EAPI Eio_File *eio_file_close(Eina_File *f,
- Eio_Done_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief Asynchronously map a file in memory.
- * @param f The file to map.
- * @param rule The rule to apply to the map.
- * @param filter_cb Callback called in the thread to validate the content of the map.
- * @param map_cb Callback called in the main loop when the file has been successfully mapped.
- * @param error_cb Callback called in the main loop when the file can't be mapped.
- * @param data Unmodified user data passed to callbacks
- * @return Pointer to the file if successful or NULL otherwise.
- *
- * The container of the Eio_File is the Eina_File.
- */
-EAPI Eio_File *eio_file_map_all(Eina_File *f,
- Eina_File_Populate rule,
- Eio_Filter_Map_Cb filter_cb,
- Eio_Map_Cb map_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief Asynchronously map a part of a file in memory.
- * @param f The file to map.
- * @param rule The rule to apply to the map.
- * @param offset The offset inside the file
- * @param length The length of the memory to map
- * @param filter_cb Callback called in the thread to validate the content of the map.
- * @param map_cb Callback called in the main loop when the file has been successfully mapped.
- * @param error_cb Callback called in the main loop when the file can't be mapped.
- * @param data Unmodified user data passed to callbacks
- * @return Pointer to the file if successful or NULL otherwise.
- *
- * The container of the Eio_File is the Eina_File.
- */
-EAPI Eio_File *eio_file_map_new(Eina_File *f,
- Eina_File_Populate rule,
- unsigned long int offset,
- unsigned long int length,
- Eio_Filter_Map_Cb filter_cb,
- Eio_Map_Cb map_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @}
- */
-
-/**
- * @defgroup Eio_Eet Eio asynchronous API for Eet file.
- * @ingroup Eio
- *
- * @brief This set of functions help in the asynchronous use of Eet
- *
- * @{
- */
-
-/**
- * @brief Open an eet file on disk, and returns a handle to it asynchronously.
- * @param filename The file path to the eet file. eg: @c "/tmp/file.eet".
- * @param mode The mode for opening. Either EET_FILE_MODE_READ,
- * EET_FILE_MODE_WRITE or EET_FILE_MODE_READ_WRITE.
- * @param eet_cb The callback to call when the file has been successfully opened.
- * @param error_cb Callback called in the main loop when the file can't be opened.
- * @param data Unmodified user data passed to callbacks
- * @return NULL in case of a failure.
- *
- * This function calls eet_open() from another thread using Ecore_Thread.
- */
-EAPI Eio_File *eio_eet_open(const char *filename,
- Eet_File_Mode mode,
- Eio_Eet_Open_Cb eet_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-/**
- * @brief Close an eet file handle and flush pending writes asynchronously.
- * @param ef A valid eet file handle.
- * @param done_cb Callback called from the main loop when the file has been closed.
- * @param error_cb Callback called in the main loop when the file can't be closed.
- * @param data Unmodified user data passed to callbacks
- * @return NULL in case of a failure.
- *
- * This function will call eet_close() from another thread by
- * using Ecore_Thread. You should assume that the Eet_File is dead after this
- * function is called.
- */
-EAPI Eio_File *eio_eet_close(Eet_File *ef,
- Eio_Done_Cb done_cb,
- Eio_Eet_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief Sync content of an eet file handle, flushing pending writes asynchronously.
- * @param ef A valid eet file handle.
- * @param done_cb Callback called from the main loop when the file has been synced.
- * @param error_cb Callback called in the main loop when the file can't be synced.
- * @param data Unmodified user data passed to callbacks
- * @return NULL in case of a failure.
- *
- * This function will call eet_sync() from another thread. As long as the done_cb or
- * error_cb haven't be called, you must keep @p ef open.
- */
-EAPI Eio_File *eio_eet_sync(Eet_File *ef,
- Eio_Done_Cb done_cb,
- Eio_Eet_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief Write a data structure from memory and store in an eet file
- * using a cipher asynchronously.
- * @param ef The eet file handle to write to.
- * @param edd The data descriptor to use when encoding.
- * @param name The key to store the data under in the eet file.
- * @param cipher_key The key to use as cipher.
- * @param write_data A pointer to the data structure to save and encode.
- * @param compress Compression flags for storage.
- * @param done_cb Callback called from the main loop when the data has been put in the Eet_File.
- * @param error_cb Callback called in the main loop when the file can't be written.
- * @param user_data Private data given to each callback.
- * @return NULL in case of a failure.
- */
-EAPI Eio_File *eio_eet_data_write_cipher(Eet_File *ef,
- Eet_Data_Descriptor *edd,
- const char *name,
- const char *cipher_key,
- void *write_data,
- int compress,
- Eio_Done_Int_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *user_data);
-
-/**
- * @brief Read a data structure from an eet file and decodes it using a cipher asynchronously.
- * @param ef The eet file handle to read from.
- * @param edd The data descriptor handle to use when decoding.
- * @param name The key the data is stored under in the eet file.
- * @param cipher_key The key to use as cipher.
- * @param done_cb Callback called from the main loop when the data has been read and decoded.
- * @param error_cb Callback called in the main loop when the data can't be read.
- * @param data Unmodified user data passed to callbacks
- * @return NULL in case of a failure.
- */
-EAPI Eio_File *eio_eet_data_read_cipher(Eet_File *ef,
- Eet_Data_Descriptor *edd,
- const char *name,
- const char *cipher_key,
- Eio_Done_ERead_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief Write image data to the named key in an eet file asynchronously.
- * @param ef A valid eet file handle opened for writing.
- * @param name Name of the entry. eg: "/base/file_i_want".
- * @param cipher_key The key to use as cipher.
- * @param write_data A pointer to the image pixel data.
- * @param w The width of the image in pixels.
- * @param h The height of the image in pixels.
- * @param alpha The alpha channel flag.
- * @param compress The compression amount.
- * @param quality The quality encoding amount.
- * @param lossy The lossiness flag.
- * @param done_cb Callback called from the main loop when the data has been put in the Eet_File.
- * @param error_cb Callback called in the main loop when the file can't be written.
- * @param user_data Private data given to each callback.
- * @return NULL in case of a failure.
- */
-EAPI Eio_File *eio_eet_data_image_write_cipher(Eet_File *ef,
- const char *name,
- const char *cipher_key,
- void *write_data,
- unsigned int w,
- unsigned int h,
- int alpha,
- int compress,
- int quality,
- int lossy,
- Eio_Done_Int_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *user_data);
-
-/**
- * @brief Read a specified entry from an eet file and return data
- * @param ef A valid eet file handle opened for reading.
- * @param name Name of the entry. eg: "/base/file_i_want".
- * @param done_cb Callback called from the main loop when the data has been read.
- * @param error_cb Callback called in the main loop when the data can't be read.
- * @param data Unmodified user data passed to callbacks
- * @return NULL in case of a failure.
- */
-EAPI Eio_File *eio_eet_read_direct(Eet_File *ef,
- const char *name,
- Eio_Done_Data_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief Read a specified entry from an eet file and return data
- * @param ef A valid eet file handle opened for reading.
- * @param name Name of the entry. eg: "/base/file_i_want".
- * @param cipher_key The key to use as cipher.
- * @param done_cb Callback called from the main loop when the data has been read.
- * @param error_cb Callback called in the main loop when the data can't be read.
- * @param data Unmodified user data passed to callbacks
- * @return NULL in case of a failure.
- */
-EAPI Eio_File *eio_eet_read_cipher(Eet_File *ef,
- const char *name,
- const char *cipher_key,
- Eio_Done_Read_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *data);
-
-/**
- * @brief Write a specified entry to an eet file handle using a cipher.
- * @param ef A valid eet file handle opened for writing.
- * @param name Name of the entry. eg: "/base/file_i_want".
- * @param write_data Pointer to the data to be stored.
- * @param size Length in bytes in the data to be stored.
- * @param compress Compression flags (1 == compress, 0 = don't compress).
- * @param cipher_key The key to use as cipher.
- * @param done_cb Callback called from the main loop when the data has been put in the Eet_File.
- * @param error_cb Callback called in the main loop when the file can't be written.
- * @param user_data Private data given to each callback.
- * @return NULL in case of a failure.
- */
-EAPI Eio_File *eio_eet_write_cipher(Eet_File *ef,
- const char *name,
- void *write_data,
- int size,
- int compress,
- const char *cipher_key,
- Eio_Done_Int_Cb done_cb,
- Eio_Error_Cb error_cb,
- const void *user_data);
-
-/**
- * @}
- */
-
-/**
- * @defgroup Eio_Monitor Eio file and directory monitoring API
- * @ingroup Eio
- *
- * @brief These function monitor changes in directories and files
- *
- * These functions use the best available method to monitor changes on a specified directory
- * or file. They send ecore events when changes occur, and they maintain internal refcounts to
- * reduce resource consumption on duplicate monitor targets.
- *
- * @{
- */
-
-EAPI extern int EIO_MONITOR_FILE_CREATED; /**< A new file was created in a watched directory */
-EAPI extern int EIO_MONITOR_FILE_DELETED; /**< A watched file was deleted, or a file in a watched directory was deleted */
-EAPI extern int EIO_MONITOR_FILE_MODIFIED; /**< A file was modified in a watched directory */
-EAPI extern int EIO_MONITOR_FILE_CLOSED; /**< A file was closed in a watched directory. This event is never sent on Windows and OSX */
-EAPI extern int EIO_MONITOR_DIRECTORY_CREATED; /**< A new directory was created in a watched directory */
-EAPI extern int EIO_MONITOR_DIRECTORY_DELETED; /**< A directory has been deleted: this can be either a watched directory or one of its subdirectories */
-EAPI extern int EIO_MONITOR_DIRECTORY_MODIFIED; /**< A directory has been modified in a watched directory */
-EAPI extern int EIO_MONITOR_DIRECTORY_CLOSED; /**< A directory has been closed in a watched directory. This event is never sent on Windows and OSX */
-EAPI extern int EIO_MONITOR_SELF_RENAME; /**< The monitored path has been renamed, an error could happen just after if the renamed path doesn't exist. This event is never sent on OSX */
-EAPI extern int EIO_MONITOR_SELF_DELETED; /**< The monitored path has been removed. This event is never sent on OSX */
-EAPI extern int EIO_MONITOR_ERROR; /**< During operation the monitor failed and will no longer work. eio_monitor_del must be called on it. */
-
-typedef struct _Eio_Monitor Eio_Monitor;
-
-typedef struct _Eio_Monitor_Error Eio_Monitor_Error;
-typedef struct _Eio_Monitor_Event Eio_Monitor_Event;
-
-struct _Eio_Monitor_Error
-{
- Eio_Monitor *monitor;
- int error;
-};
-
-struct _Eio_Monitor_Event
-{
- Eio_Monitor *monitor;
- const char *filename;
-};
-
-/**
- * @brief Adds a file/directory to monitor (inotify mechanism)
- * @param path file/directory to monitor
- * @return NULL in case of a failure or a pointer to the monitor in case of
- * success.
- *
- * This function will add the given path to its internal
- * list of files to monitor. It utilizes the inotify mechanism
- * introduced in kernel 2.6.13 for passive monitoring.
- */
-EAPI Eio_Monitor *eio_monitor_add(const char *path);
-
-/**
- * @brief Adds a file/directory to monitor
- * @param path file/directory to monitor
- * @return NULL in case of a failure or a pointer to the monitor in case of
- * success.
- * @warning Do NOT pass non-stringshared strings to this function!
- * If you don't know what this means, use eio_monitor_add().
- *
- * This fuction is just like eio_monitor_add(), however the string passed by
- * argument must be created using eina_stringshare_add().
- */
-EAPI Eio_Monitor *eio_monitor_stringshared_add(const char *path);
-
-/**
- * @brief Deletes a path from the “watched” list
- * @param monitor The Eio_Monitor you want to stop watching.
- * It can only be an Eio_Monitor returned to you from calling
- * eio_monitor_add() or eio_monitor_stringshared_add()
- */
-EAPI void eio_monitor_del(Eio_Monitor *monitor);
-
-/**
- * @brief returns the path being watched by the given
- * Eio_Monitor.
- * @param monitor Eio_Monitor to return the path of
- * @return The stringshared path belonging to @p monitor
- */
-EAPI const char *eio_monitor_path_get(Eio_Monitor *monitor);
-
-/**
- * @}
- */
-
#include "eio_inline_helper.x"
+#define EIO_VERSION_MAJOR EFL_VERSION_MAJOR
+#define EIO_VERSION_MINOR EFL_VERSION_MINOR
+
#ifdef __cplusplus
}
#endif
diff --git a/src/lib/eio/Eio_Eo.h b/src/lib/eio/Eio_Eo.h
new file mode 100644
index 0000000000..ebd2d502fd
--- /dev/null
+++ b/src/lib/eio/Eio_Eo.h
@@ -0,0 +1,13 @@
+/* This include has been added to support Eo in Eio */
+#include <Eo.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "eio_job.eo.h"
+#include "eio_sentry.eo.h"
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/lib/eio/Eio_Legacy.h b/src/lib/eio/Eio_Legacy.h
new file mode 100644
index 0000000000..833a21499d
--- /dev/null
+++ b/src/lib/eio/Eio_Legacy.h
@@ -0,0 +1,1256 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /**
+ * @typedef Eio_Version
+ * Represents the current version of EIO
+ */
+ typedef struct _Eio_Version
+ {
+ int major; /**< Major version number */
+ int minor; /**< Minor version number */
+ int micro; /**< Micro version number */
+ int revision; /**< Revision number */
+ } Eio_Version;
+
+ EAPI extern Eio_Version *eio_version;
+
+/**
+ * @file
+ * @brief Eio asynchronous input/output library
+ *
+ * These routines are used for Eio.
+ */
+
+/**
+ * @page eio_main Eio
+ *
+ * @date 2012 (created)
+ *
+ * @section toc Table of Contents
+ *
+ * @li @ref eio_main_intro
+ * @li @ref eio_main_compiling
+ * @li @ref eio_main_next_steps
+ * @li @ref eio_main_intro_example
+ *
+ * @section eio_main_intro Introduction
+ *
+ * The Eio library is a library that implements an API for asynchronous
+ * input/output operation. Most operations are done in a separate thread
+ * to prevent lock. See @ref Eio_Group. Some helper to work on data
+ * received in Eio callback are also provided see @ref Eio_Helper.
+ * It is also possible to work asynchronously on Eina_File with @ref Eio_Map
+ * or on Eet_File with @ref Eio_Eet. It comes with way to manipulate
+ * eXtended attribute asynchronous with @ref Eio_Xattr.
+ *
+ * This library is cross-platform and can be compiled and used on
+ * Linux, BSD, Opensolaris and Windows (XP and CE). It is heavily
+ * based on @ref Ecore_Main_Loop_Group.
+ *
+ * @section eio_main_compiling How to compile
+ *
+ * Eio is a library your application links to. The procedure for this is
+ * very simple. You simply have to compile your application with the
+ * appropriate compiler flags that the @c pkg-config script outputs. For
+ * example:
+ *
+ * Compiling C or C++ files into object files:
+ *
+ * @verbatim
+ gcc -c -o main.o main.c `pkg-config --cflags eio`
+ @endverbatim
+ *
+ * Linking object files into a binary executable:
+ *
+ * @verbatim
+ gcc -o my_application main.o `pkg-config --libs eio`
+ @endverbatim
+ *
+ * See @ref pkgconfig
+ *
+ * @section eio_main_next_steps Next Steps
+ *
+ * After you understand what Eio is and installed it on your system
+ * you should proceed understand the programming interface.
+ *
+ * Recommended reading:
+ *
+ * @li @ref Eio_Helper for common functions and library initialization.
+ * @li @ref Eio_List for listing files asynchronous.
+ * @li @ref Eio_Management for anyone who want to do a file manager (copy, rm, ...).
+ * @li @ref Eio_Map to manipulate files asynchronously (mmap).
+ * @li @ref Eio_Xattr to access file extended attributes (xattr).
+ * @li @ref Eio_Monitor to monitor for file changes (inotify).
+ * @li @ref Eio_Eet to access Eet files asynchronously.
+ *
+ * @section eio_main_intro_example Introductory Example
+ *
+ * @include eio_file_ls.c
+ *
+ * More examples can be found at @ref eio_examples.
+ *
+ */
+
+/**
+ * @enum _Eio_File_Op
+ *
+ * @brief Input/Output operations on files.
+ *
+ * This enum represents the operations that can be done.
+ */
+enum _Eio_File_Op
+{
+ EIO_FILE_COPY, /**< I/O operation is about a specific file copy */
+ EIO_FILE_MOVE, /**< I/O operation is about a specific file move */
+ EIO_DIR_COPY, /**< I/O operation is about a specific directory copy */
+ EIO_DIR_MOVE, /**< I/O operation is about a specific directory move */
+ /** I/O operation is about destroying a path:
+ * source will point to base path to be destroyed,
+ * and dest will point to to path destroyed by this I/O
+ */
+ EIO_UNLINK,
+ EIO_FILE_GETPWNAM, /**< I/O operation is trying to get uid from user name */
+ EIO_FILE_GETGRNAM /**< I/O operation is trying to get gid from user name */
+};
+
+/**
+ * @typedef Eio_File_Op
+ * Input/Output operations on files.
+ */
+typedef enum _Eio_File_Op Eio_File_Op;
+
+/**
+ * @defgroup Eio_List Eio file listing API
+ * @ingroup Eio
+ *
+ * @brief This functions helps list files asynchronously.
+ *
+ * This set of functions work on top of Eina_File and Ecore_Thread
+ * to list files under various condition.
+ *
+ * @{
+ */
+
+/**
+ * @typedef Eio_File
+ * Generic asynchronous I/O reference.
+ */
+typedef struct _Eio_File Eio_File;
+
+/**
+ * @typedef Eio_Progress
+ * Progress information on a specific operation.
+ */
+typedef struct _Eio_Progress Eio_Progress;
+
+typedef Eina_Bool (*Eio_Filter_Cb)(void *data, Eio_File *handler, const char *file);
+typedef void (*Eio_Main_Cb)(void *data, Eio_File *handler, const char *file);
+
+typedef Eina_Bool (*Eio_Filter_Direct_Cb)(void *data, Eio_File *handler, const Eina_File_Direct_Info *info);
+typedef Eina_Bool (*Eio_Filter_Dir_Cb)(void *data, Eio_File *handler, Eina_File_Direct_Info *info);
+typedef void (*Eio_Main_Direct_Cb)(void *data, Eio_File *handler, const Eina_File_Direct_Info *info);
+
+typedef void (*Eio_Stat_Cb)(void *data, Eio_File *handler, const Eina_Stat *stat);
+typedef void (*Eio_Progress_Cb)(void *data, Eio_File *handler, const Eio_Progress *info);
+
+typedef void (*Eio_Eet_Open_Cb)(void *data, Eio_File *handler, Eet_File *file);
+typedef void (*Eio_Open_Cb)(void *data, Eio_File *handler, Eina_File *file);
+typedef Eina_Bool (*Eio_Filter_Map_Cb)(void *data, Eio_File *handler, void *map, size_t length);
+typedef void (*Eio_Map_Cb)(void *data, Eio_File *handler, void *map, size_t length);
+
+typedef void (*Eio_Done_Data_Cb)(void *data, Eio_File *handler, const char *read_data, unsigned int size);
+typedef void (*Eio_Done_String_Cb)(void *data, Eio_File *handler, const char *xattr_string);
+typedef void (*Eio_Done_Double_Cb)(void *data, Eio_File *handler, double xattr_double);
+typedef void (*Eio_Done_Int_Cb)(void *data, Eio_File *handler, int i);
+
+typedef void (*Eio_Done_ERead_Cb)(void *data, Eio_File *handler, void *decoded);
+typedef void (*Eio_Done_Read_Cb)(void *data, Eio_File *handler, void *read_data, unsigned int size);
+typedef void (*Eio_Done_Cb)(void *data, Eio_File *handler);
+typedef void (*Eio_Error_Cb)(void *data, Eio_File *handler, int error);
+typedef void (*Eio_Eet_Error_Cb)(void *data, Eio_File *handler, Eet_Error err);
+
+/**
+ * @struct _Eio_Progress
+ * @brief Represents the current progress of the operation.
+ */
+struct _Eio_Progress
+{
+ Eio_File_Op op; /**< I/O type */
+
+ long long current; /**< Current step in the I/O operation */
+ long long max; /**< Number of total steps to complete this I/O */
+ float percent; /**< Percent done for the I/O operation */
+
+ const char *source; /**< source of the I/O operation */
+ const char *dest; /**< target of the I/O operation */
+};
+
+/**
+ * @brief List contents of a directory without locking your app.
+ * @param dir The directory to list.
+ * @param filter_cb Callback used to decide if the file will be passed to main_cb
+ * @param main_cb Callback called for each listed file if it was not filtered.
+ * @param done_cb Callback called when the ls operation is done.
+ * @param error_cb Callback called when either the directory could not be opened or the operation has been canceled.
+ * @param data Unmodified user data passed to callbacks
+ * @return A reference to the I/O operation.
+ *
+ * This function is responsible for listing the content of a directory without blocking your application.
+ * It's equivalent to the "ls" shell command. Every file will be passed to the
+ * filter_cb, so it's your job to decide if you want to pass the file to the
+ * main_cb or not. Return EINA_TRUE to pass it to the main_cb or EINA_FALSE to
+ * ignore it. It runs eina_file_ls() in a separate thread using
+ * ecore_thread_feedback_run().
+ *
+ * @see eina_file_ls()
+ * @see ecore_thread_feedback_run()
+ * @see eio_file_direct_ls()
+ * @see eio_file_stat_ls()
+ */
+EAPI Eio_File *eio_file_ls(const char *dir,
+ Eio_Filter_Cb filter_cb,
+ Eio_Main_Cb main_cb,
+ Eio_Done_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief List contents of a directory without locking your app.
+ * @param dir The directory to list.
+ * @param filter_cb Callback used to decide if the file will be passed to main_cb
+ * @param main_cb Callback called from the main loop for each accepted file (not filtered).
+ * @param done_cb Callback called from the main loop after the contents of the directory has been listed.
+ * @param error_cb Callback called from the main loop when either the directory could not be opened or the operation has been canceled.
+ * @param data Unmodified user data passed to callbacks
+ * @return A reference to the I/O operation.
+ *
+ * eio_file_direct_ls() runs eina_file_direct_ls() in a separate thread using
+ * ecore_thread_feedback_run(). This prevents any blocking in your apps.
+ * Every file will be passed to the filter_cb, so it's your job to decide if you
+ * want to pass the file to the main_cb or not. Return EINA_TRUE to pass it to
+ * the main_cb or EINA_FALSE to ignore it.
+ *
+ * @warning If readdir_r doesn't contain file type information, file type is
+ * EINA_FILE_UNKNOWN.
+ *
+ * @note The iterator walks over '.' and '..' without returning them.
+ * @note The difference between this function and eina_file_stat_ls() is that
+ * it may not get the file type information however it is likely to be
+ * faster.
+ *
+ * @see eio_file_stat_ls()
+ * @see eina_file_direct_ls()
+ * @see ecore_thread_feedback_run()
+ */
+EAPI Eio_File *eio_file_direct_ls(const char *dir,
+ Eio_Filter_Direct_Cb filter_cb,
+ Eio_Main_Direct_Cb main_cb,
+ Eio_Done_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief List content of a directory without locking your app.
+ * @param dir The directory to list.
+ * @param filter_cb Callback used to decide if the file will be passed to main_cb
+ * @param main_cb Callback called from the main loop for each accepted file (not filtered).
+ * @param done_cb Callback called from the main loop after the contents of the directory has been listed.
+ * @param error_cb Callback called from the main loop when either the directory could not be opened or the operation has been canceled.
+ * @param data Unmodified user data passed to callbacks
+ * @return A reference to the I/O operation.
+ *
+ * Every file will be passed to the filter_cb, so it's your job to decide if you
+ * want to pass the file to the main_cb or not. Return EINA_TRUE to pass it to
+ * the main_cb or EINA_FALSE to ignore it. eio_file_stat_ls() run eina_file_stat_ls()
+ * in a separate thread using ecore_thread_feedback_run().
+ *
+ * @note The iterator walks over '.' and '..' without returning them.
+ * @note The difference between this function and eio_file_direct_ls() is that
+ * it guarantees the file type information to be correct by incurring a
+ * possible performance penalty.
+ *
+ * @see eio_file_stat_ls()
+ * @see eina_file_stat_ls()
+ * @see ecore_thread_feedback_run()
+ */
+EAPI Eio_File *eio_file_stat_ls(const char *dir,
+ Eio_Filter_Direct_Cb filter_cb,
+ Eio_Main_Direct_Cb main_cb,
+ Eio_Done_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief List the content of a directory and all its sub-content asynchronously
+ * @param dir The directory to list.
+ * @param filter_cb Callback used to decide if the file will be passed to main_cb
+ * @param main_cb Callback called from the main loop for each accepted file (not filtered).
+ * @param done_cb Callback called from the main loop after the contents of the directory has been listed.
+ * @param error_cb Callback called from the main loop when either the directory could not be opened or the operation has been canceled.
+ * @param data Unmodified user data passed to callbacks
+ * @return A reference to the I/O operation.
+ *
+ * eio_dir_stat_ls() runs eina_file_stat_ls() recursively in a separate thread using
+ * ecore_thread_feedback_run(). This prevents any blocking in your apps.
+ * Every file will be passed to the
+ * filter_cb, so it's your job to decide if you want to pass the file to the
+ * main_cb or not. Return EINA_TRUE to pass it to the main_cb or EINA_FALSE to
+ * ignore it.
+ *
+ * @see eio_file_stat_ls()
+ * @see eio_dir_direct_ls()
+ * @see eina_file_stat_ls()
+ * @see ecore_thread_feedback_run()
+ */
+EAPI Eio_File *eio_dir_stat_ls(const char *dir,
+ Eio_Filter_Direct_Cb filter_cb,
+ Eio_Main_Direct_Cb main_cb,
+ Eio_Done_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief List the content of a directory and all its sub-content asynchronously
+ * @param dir The directory to list.
+ * @param filter_cb Callback used to decide if the file will be passed to main_cb
+ * @param main_cb Callback called from the main loop for each accepted file (not filtered).
+ * @param done_cb Callback called from the main loop after the contents of the directory has been listed.
+ * @param error_cb Callback called from the main loop when either the directory could not be opened or the operation has been canceled.
+ * @param data Unmodified user data passed to callbacks
+ * @return A reference to the I/O operation.
+ *
+ * eio_dir_direct_ls() runs eina_file_direct_ls() recursively in a separate thread using
+ * ecore_thread_feedback_run(). This prevents any blocking in your apps.
+ * Every file will be passed to the filter_cb, so it's your job to decide if you
+ * want to pass the file to the main_cb or not. Return EINA_TRUE to pass it to
+ * the main_cb or EINA_FALSE to ignore it.
+ *
+ * @see eio_file_direct_ls()
+ * @see eio_dir_stat_ls()
+ * @see eina_file_direct_ls()
+ * @see ecore_thread_feedback_run()
+ */
+EAPI Eio_File *eio_dir_direct_ls(const char *dir,
+ Eio_Filter_Dir_Cb filter_cb,
+ Eio_Main_Direct_Cb main_cb,
+ Eio_Done_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief Stat a file/directory.
+ * @param path The path to stat.
+ * @param done_cb Callback called from the main loop when stat was successfully called.
+ * @param error_cb Callback called from the main loop when stat failed or has been canceled.
+ * @param data Unmodified user data passed to callbacks
+ * @return A reference to the I/O operation.
+ *
+ * eio_file_direct_stat calls stat in another thread. This prevents any blocking in your apps.
+ */
+EAPI Eio_File *eio_file_direct_stat(const char *path,
+ Eio_Stat_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Eio_Management Eio file management API.
+ *
+ * @brief A set of function to manage file asynchronously.
+ *
+ * The function provided by this API are the one useful for any
+ * file manager. Like moving or copying a file, unlinking it, changing
+ * it's access right, ...
+ *
+ * @{
+ */
+
+/**
+ * @brief Change rights of a path.
+ * @param path The directory path to change access rights.
+ * @param mode The permission to set, follow (mode & ~umask & 0777).
+ * @param done_cb Callback called when the operation is completed.
+ * @param error_cb Callback called from if something goes wrong.
+ * @param data Unmodified user data passed to callbacks.
+ * @return A reference to the I/O operation.
+ *
+ * Set a new permission of a path changing it to the mode passed as argument.
+ * It's equivalent to the chmod command.
+ */
+EAPI Eio_File *eio_file_chmod(const char *path,
+ mode_t mode,
+ Eio_Done_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief Change owner of a path.
+ * @param path The directory path to change owner.
+ * @param user The new user to set (can be NULL).
+ * @param group The new group to set (can be NULL).
+ * @param done_cb Callback called when the operation is completed.
+ * @param error_cb Callback called from if something goes wrong.
+ * @param data Unmodified user data passed to callbacks
+ * @return A reference to the I/O operation.
+ *
+ * This function will change the owner of a path, setting it to the user and
+ * group passed as argument. It's equivalent to the chown shell command.
+ */
+EAPI Eio_File *eio_file_chown(const char *path,
+ const char *user,
+ const char *group,
+ Eio_Done_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief Unlink a file/directory.
+ * @param path The path to unlink.
+ * @param done_cb Callback called when the operation is completed.
+ * @param error_cb Callback called from if something goes wrong.
+ * @param data Unmodified user data passed to callbacks.
+ * @return A reference to the I/O operation.
+ *
+ * This function will erase a file.
+ */
+EAPI Eio_File *eio_file_unlink(const char *path,
+ Eio_Done_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief Create a new directory.
+ * @param path The directory path to create.
+ * @param mode The permission to set, follow (mode & ~umask & 0777).
+ * @param done_cb Callback called when the operation is completed.
+ * @param error_cb Callback called from if something goes wrong.
+ * @param data Unmodified user data passed to callbacks
+ * @return A reference to the I/O operation.
+ *
+ * Creates a new directory using the mode provided.
+ */
+EAPI Eio_File *eio_file_mkdir(const char *path,
+ mode_t mode,
+ Eio_Done_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief Move a file asynchronously
+ * @param source Should be the name of the file to move the data from.
+ * @param dest Should be the name of the file to move the data to.
+ * @param progress_cb Callback called to know the progress of the move.
+ * @param done_cb Callback called when the move is done.
+ * @param error_cb Callback called when something goes wrong.
+ * @param data Unmodified user data passed to callbacks
+ * @return A reference to the I/O operation.
+ *
+ * @return an Eio_File pointer, handler to the move operation, can be used to cancel the operation
+ *
+ * This function will copy a file from source to dest. It will try to use splice
+ * if possible, if not it will fallback to mmap/write. It will try to preserve
+ * access rights, but not user/group identification.
+ */
+EAPI Eio_File *eio_file_move(const char *source,
+ const char *dest,
+ Eio_Progress_Cb progress_cb,
+ Eio_Done_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief Copy a file asynchronously
+ * @param source Should be the name of the file to copy the data from.
+ * @param dest Should be the name of the file to copy the data to.
+ * @param progress_cb Callback called to know the progress of the copy.
+ * @param done_cb Callback called when the copy is done.
+ * @param error_cb Callback called when something goes wrong.
+ * @param data Unmodified user data passed to callbacks
+ *
+ * @return an Eio_File pointer, handler to the copy operation, can be used to cancel the operation
+ *
+ * This function will copy a file from source to dest. It will try to use splice
+ * if possible, if not it will fallback to mmap/write. It will try to preserve
+ * access rights, but not user/group identification.
+ */
+EAPI Eio_File *eio_file_copy(const char *source,
+ const char *dest,
+ Eio_Progress_Cb progress_cb,
+ Eio_Done_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief Move a directory and its content asynchronously
+ * @param source Should be the name of the directory to copy the data from.
+ * @param dest Should be the name of the directory to copy the data to.
+ * @param filter_cb Possible to deny the move of some files/directories.
+ * @param progress_cb Callback called to know the progress of the copy.
+ * @param done_cb Callback called when the copy is done.
+ * @param error_cb Callback called when something goes wrong.
+ * @param data Unmodified user data passed to callbacks
+ * @return A reference to the I/O operation.
+ *
+ * @return an Eio_File pointer, handler to the move operation, can be used to cancel the operation
+ *
+ * This function will move a directory and all its content from source to dest.
+ * It will try first to rename the directory, if not it will try to use splice
+ * if possible, if not it will fallback to mmap/write.
+ * It will try to preserve access rights, but not user/group identity.
+ * Every file will be passed to the filter_cb, so it's your job to decide if you
+ * want to pass the file to the main_cb or not. Return EINA_TRUE to pass it to
+ * the main_cb or EINA_FALSE to ignore it.
+ *
+ * @note if a rename occurs, the filter callback will not be called.
+ */
+EAPI Eio_File *eio_dir_move(const char *source,
+ const char *dest,
+ Eio_Filter_Direct_Cb filter_cb,
+ Eio_Progress_Cb progress_cb,
+ Eio_Done_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief Copy a directory and its content asynchronously
+ * @param source Should be the name of the directory to copy the data from.
+ * @param dest Should be the name of the directory to copy the data to.
+ * @param filter_cb Possible to deny the move of some files/directories.
+ * @param progress_cb Callback called to know the progress of the copy.
+ * @param done_cb Callback called when the copy is done.
+ * @param error_cb Callback called when something goes wrong.
+ * @param data Unmodified user data passed to callbacks
+ * @return A reference to the I/O operation.
+ *
+ * @return an Eio_File pointer, handler to the copy operation, can be used to cancel the operation
+ *
+ * This function will copy a directory and all its content from source to dest.
+ * It will try to use splice if possible, if not it will fallback to mmap/write.
+ * It will try to preserve access rights, but not user/group identity.
+ * Every file will be passed to the filter_cb, so it's your job to decide if you
+ * want to pass the file to the main_cb or not. Return EINA_TRUE to pass it to
+ * the main_cb or EINA_FALSE to ignore it.
+ */
+EAPI Eio_File *eio_dir_copy(const char *source,
+ const char *dest,
+ Eio_Filter_Direct_Cb filter_cb,
+ Eio_Progress_Cb progress_cb,
+ Eio_Done_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief Remove a directory and its content asynchronously
+ * @param path Should be the name of the directory to destroy.
+ * @param filter_cb Possible to deny the move of some files/directories.
+ * @param progress_cb Callback called to know the progress of the copy.
+ * @param done_cb Callback called when the copy is done.
+ * @param error_cb Callback called when something goes wrong.
+ * @param data Unmodified user data passed to callbacks
+ * @return A reference to the I/O operation.
+ *
+ * @return an Eio_File pointer, handler to the unlink operation, can be used to cancel the operation
+ *
+ * This function will remove a directory and all its content.
+ * Every file will be passed to the filter_cb, so it's your job to decide if you
+ * want to pass the file to the main_cb or not. Return EINA_TRUE to pass it to
+ * the main_cb or EINA_FALSE to ignore it.
+ */
+EAPI Eio_File *eio_dir_unlink(const char *path,
+ Eio_Filter_Direct_Cb filter_cb,
+ Eio_Progress_Cb progress_cb,
+ Eio_Done_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Eio_Xattr Eio manipulation of eXtended attribute.
+ * @ingroup Eio
+ *
+ * @brief A set of function to manipulate data associated with a specific file
+ *
+ * The functions provided by this API are responsible to manage Extended
+ * attribute files. Like file authors, character encoding, checksum, etc.
+ * @{
+ */
+
+/**
+ * @brief Asynchronously list all eXtended attribute
+ * @param path The path to get the eXtended attribute from.
+ * @param filter_cb Callback called in the thread to validate the eXtended attribute.
+ * @param main_cb Callback called in the main loop for each accepted eXtended attribute.
+ * @param done_cb Callback called in the main loop when the all the eXtended attribute have been listed.
+ * @param error_cb Callback called in the main loop when something goes wrong during the listing of the eXtended attribute.
+ * @param data Unmodified user data passed to callbacks
+ * @return A reference to the I/O operation.
+ */
+EAPI Eio_File *eio_file_xattr(const char *path,
+ Eio_Filter_Cb filter_cb,
+ Eio_Main_Cb main_cb,
+ Eio_Done_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief Define an extented attribute on a file/directory.
+ * @param path The path to set the attribute on.
+ * @param attribute The name of the attribute to define.
+ * @param xattr_int The value to link the attribute with.
+ * @param flags Whether to insert, replace or create the attribute.
+ * @param done_cb The callback called from the main loop when setxattr succeeded.
+ * @param error_cb The callback called from the main loop when setxattr failed.
+ * @param data Unmodified user data passed to callbacks
+ * @return A reference to the I/O operation.
+ *
+ * eio_file_xattr_int_set calls eina_xattr_int_set from another thread. This prevents blocking in your apps. If
+ * the writing succeeded, the done_cb will be called even if a cancel was requested, but came too late.
+ */
+EAPI Eio_File *eio_file_xattr_int_set(const char *path,
+ const char *attribute,
+ int xattr_int,
+ Eina_Xattr_Flags flags,
+ Eio_Done_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief Define an extented attribute on a file/directory.
+ * @param path The path to set the attribute on.
+ * @param attribute The name of the attribute to define.
+ * @param xattr_double The value to link the attribute with.
+ * @param flags Whether to insert, replace or create the attribute.
+ * @param done_cb The callback called from the main loop when setxattr succeeded.
+ * @param error_cb The callback called from the main loop when setxattr failed.
+ * @param data Unmodified user data passed to callbacks
+ * @return A reference to the I/O operation.
+ *
+ * eio_file_xattr_double_set calls eina_xattr_double_set from another thread. This prevents blocking in your apps. If
+ * the writing succeeded, the done_cb will be called even if a cancel was requested, but came too late.
+ */
+EAPI Eio_File *eio_file_xattr_double_set(const char *path,
+ const char *attribute,
+ double xattr_double,
+ Eina_Xattr_Flags flags,
+ Eio_Done_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+/**
+ * @brief Define a string extented attribute on a file/directory.
+ * @param path The path to set the attribute on.
+ * @param attribute The name of the attribute to define.
+ * @param xattr_string The string to link the attribute with.
+ * @param flags Whether to insert, replace or create the attribute.
+ * @param done_cb The callback called from the main loop when setxattr succeeded.
+ * @param error_cb The callback called from the main loop when setxattr failed.
+ * @param data Unmodified user data passed to callbacks
+ * @return A reference to the I/O operation.
+ *
+ * eio_file_xattr_string_set calls eina_xattr_string_set from another thread. This prevents blocking in your apps. If
+ * the writing succeeded, the done_cb will be called even if a cancel was requested, but came too late.
+ */
+EAPI Eio_File *eio_file_xattr_string_set(const char *path,
+ const char *attribute,
+ const char *xattr_string,
+ Eina_Xattr_Flags flags,
+ Eio_Done_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+/**
+ * @brief Define an extented attribute on a file/directory.
+ * @param path The path to set the attribute on.
+ * @param attribute The name of the attribute to define.
+ * @param xattr_data The data to link the attribute with.
+ * @param xattr_size The size of the data to set.
+ * @param flags Whether to insert, replace or create the attribute.
+ * @param done_cb The callback called from the main loop when setxattr succeeded.
+ * @param error_cb The callback called from the main loop when setxattr failed.
+ * @param data Unmodified user data passed to callbacks
+ * @return A reference to the I/O operation.
+ *
+ * eio_file_xattr_set calls setxattr from another thread. This prevents blocking in your apps. If
+ * the writing succeeded, the done_cb will be called even if a cancel was requested, but came too late.
+ */
+EAPI Eio_File *eio_file_xattr_set(const char *path,
+ const char *attribute,
+ const char *xattr_data,
+ unsigned int xattr_size,
+ Eina_Xattr_Flags flags,
+ Eio_Done_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief Retrieve the extended attribute of a file/directory.
+ * @param path The path to retrieve the extended attribute from.
+ * @param attribute The name of the attribute to retrieve.
+ * @param done_cb Callback called from the main loop when getxattr succeeded.
+ * @param error_cb Callback called from the main loop when getxattr failed or has been canceled.
+ * @param data Unmodified user data passed to callbacks
+ * @return A reference to the I/O operation.
+ *
+ * eio_file_xattr_get calls getxattr from another thread. This prevents blocking in your apps.
+ */
+EAPI Eio_File *eio_file_xattr_get(const char *path,
+ const char *attribute,
+ Eio_Done_Data_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+/**
+ * @brief Retrieve a extended attribute of a file/directory.
+ * @param path The path to retrieve the extended attribute from.
+ * @param attribute The name of the attribute to retrieve.
+ * @param done_cb Callback called from the main loop when getxattr succeeded.
+ * @param error_cb Callback called from the main loop when getxattr failed or has been canceled.
+ * @param data Unmodified user data passed to callbacks
+ * @return A reference to the I/O operation.
+ *
+ * eio_file_xattr_int_get calls eina_xattr_int_get from another thread. This prevents blocking in your apps.
+ */
+EAPI Eio_File *eio_file_xattr_int_get(const char *path,
+ const char *attribute,
+ Eio_Done_Int_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+/**
+ * @brief Retrieve a extended attribute of a file/directory.
+ * @param path The path to retrieve the extended attribute from.
+ * @param attribute The name of the attribute to retrieve.
+ * @param done_cb Callback called from the main loop when getxattr succeeded.
+ * @param error_cb Callback called from the main loop when getxattr failed or has been canceled.
+ * @param data Unmodified user data passed to callbacks
+ * @return A reference to the I/O operation.
+ *
+ * eio_file_xattr_double_get calls eina_xattr_double_get from another thread. This prevents blocking in your apps.
+ */
+EAPI Eio_File *eio_file_xattr_double_get(const char *path,
+ const char *attribute,
+ Eio_Done_Double_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+/**
+ * @brief Retrieve a string extended attribute of a file/directory.
+ * @param path The path to retrieve the extended attribute from.
+ * @param attribute The name of the attribute to retrieve.
+ * @param done_cb Callback called from the main loop when getxattr succeeded.
+ * @param error_cb Callback called from the main loop when getxattr failed or has been canceled.
+ * @param data Unmodified user data passed to callbacks
+ * @return A reference to the I/O operation.
+ *
+ * eio_file_xattr_string_get calls eina_xattr_string_get from another thread. This prevents blocking in your apps.
+ */
+EAPI Eio_File *eio_file_xattr_string_get(const char *path,
+ const char *attribute,
+ Eio_Done_String_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Eio_Helper Eio Reference helper API
+ * @ingroup Eio
+ *
+ * @brief This are helper provided around core Eio API.
+ *
+ * This set of functions do provide helper to work around data
+ * provided by Eio without the need to look at system header.
+ *
+ * @{
+ */
+
+
+/**
+ * @brief Initialize eio and all its required submodule.
+ * @return the current number of eio users.
+ */
+EAPI int eio_init(void);
+
+/**
+ * @brief Shutdown eio and all its submodule if possible.
+ * @return the number of pending users of eio.
+ */
+EAPI int eio_shutdown(void);
+
+/**
+ * @brief Set the limit to the maximum amount of memory used
+ * @param limit The actual limit to set.
+ *
+ * Eio work by burst, allocating memory in a thread and moving it
+ * back to the main loop. This result in quite some huge memory
+ * usage if the main loop is to slow to cope with the speed of the
+ * thread. By setting this limit, the thread will block until
+ * enough memory has been freed to be below the limit again.
+ *
+ * By default no limit is set and any value < 0 will mean no limit.
+ *
+ * @note You should give at least a reasonable amount of memory or
+ * the thread might stall.
+ * @since 1.10
+ */
+EAPI void eio_memory_burst_limit_set(size_t limit);
+
+/**
+ * @brief Get the actual limit to the maximum amount of memory used
+ * @return The current limit being set.
+ *
+ * @since 1.10
+ * @see eio_memory_burst_limit_set
+ */
+EAPI size_t eio_memory_burst_limit_get(void);
+
+/**
+ * @brief Return the container during EIO operation
+ * @param ls The asynchronous I/O operation to retrieve container from.
+ * @return NULL if not available, a DIRP if it is.
+ *
+ * This is only available and make sense in the thread callback, not in
+ * the mainloop.
+ */
+EAPI void *eio_file_container_get(Eio_File *ls);
+
+/**
+ * @brief Cancel any Eio_File.
+ * @param ls The asynchronous I/O operation to cancel.
+ * @return EINA_FALSE if the destruction is delayed, EINA_TRUE if it's done.
+ *
+ * This will cancel any kind of I/O operation and cleanup the mess. This means
+ * that it could take time to cancel an I/O.
+ */
+EAPI Eina_Bool eio_file_cancel(Eio_File *ls);
+
+/**
+ * @brief Check if an Eio_File operation has been cancelled.
+ * @param ls The asynchronous I/O operation to check.
+ * @return EINA_TRUE if it was canceled, EINA_FALSE other wise.
+ *
+ * In case of an error it also return EINA_TRUE.
+ */
+EAPI Eina_Bool eio_file_check(Eio_File *ls);
+
+/**
+ * @brief Associate data with the current filtered file.
+ * @param ls The Eio_File ls request currently calling the filter callback.
+ * @param key The key to associate data to.
+ * @param data The data to associate the data to.
+ * @param free_cb Optionally a function to call to free the associated data,
+ * @p data is passed as the callback data parameter. If no @p free_cb is provided
+ * the user @p data remains untouched.
+ * @return EINA_TRUE if insertion was fine.
+ *
+ * This function can only be safely called from within the filter callback.
+ * If you don't need to copy the key around you can use @ref eio_file_associate_direct_add
+ */
+EAPI Eina_Bool eio_file_associate_add(Eio_File *ls,
+ const char *key,
+ const void *data, Eina_Free_Cb free_cb);
+
+/**
+ * @brief Associate data with the current filtered file.
+ * @param ls The Eio_File ls request currently calling the filter callback.
+ * @param key The key to associate data to (will not be copied, and the pointer will not be used as long as the file is not notified).
+ * @param data The data to associate the data to.
+ * @param free_cb The function to call to free the associated data, @p free_cb will be called if not specified.
+ * @return EINA_TRUE if insertion was fine.
+ *
+ * This function can only be safely called from within the filter callback.
+ * If you need eio to make a proper copy of the @p key to be safe use
+ * @ref eio_file_associate_add instead.
+ */
+EAPI Eina_Bool eio_file_associate_direct_add(Eio_File *ls,
+ const char *key,
+ const void *data, Eina_Free_Cb free_cb);
+
+/**
+ * @brief Get the data associated during the filter callback inside the main loop
+ * @param ls The Eio_File ls request currently calling the notify callback.
+ * @param key The key pointing to the data to retrieve.
+ * @return the data associated with the key or @p NULL if not found.
+ */
+EAPI void *eio_file_associate_find(Eio_File *ls, const char *key);
+
+/**
+ * @}
+ */
+
+/**
+ *
+ */
+
+/**
+ * @defgroup Eio_Map Manipulate an Eina_File asynchronously
+ * @ingroup Eio
+ *
+ * @brief This function helps when manipulating a file asynchronously.
+ *
+ * These set of functions work on top of Eina_File and Ecore_Thread to
+ * do basic operations on a file, like opening, closing and mapping a file to
+ * memory.
+ * @{
+ */
+
+/**
+ * @brief Asynchronously open a file.
+ * @param name The file to open.
+ * @param shared If it's a shared memory file.
+ * @param open_cb Callback called in the main loop when the file has been successfully opened.
+ * @param error_cb Callback called in the main loop when the file couldn't be opened.
+ * @param data Unmodified user data passed to callbacks
+ * @return Pointer to the file if successful or NULL otherwise.
+ *
+ */
+EAPI Eio_File *eio_file_open(const char *name, Eina_Bool shared,
+ Eio_Open_Cb open_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief Asynchronously close a file.
+ * @param f The file to close.
+ * @param done_cb Callback called in the main loop when the file has been successfully closed.
+ * @param error_cb Callback called in the main loop when the file couldn't be closed.
+ * @param data Unmodified user data passed to callbacks
+ * @return Pointer to the file if successful or NULL otherwise.
+ */
+EAPI Eio_File *eio_file_close(Eina_File *f,
+ Eio_Done_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief Asynchronously map a file in memory.
+ * @param f The file to map.
+ * @param rule The rule to apply to the map.
+ * @param filter_cb Callback called in the thread to validate the content of the map.
+ * @param map_cb Callback called in the main loop when the file has been successfully mapped.
+ * @param error_cb Callback called in the main loop when the file can't be mapped.
+ * @param data Unmodified user data passed to callbacks
+ * @return Pointer to the file if successful or NULL otherwise.
+ *
+ * The container of the Eio_File is the Eina_File.
+ */
+EAPI Eio_File *eio_file_map_all(Eina_File *f,
+ Eina_File_Populate rule,
+ Eio_Filter_Map_Cb filter_cb,
+ Eio_Map_Cb map_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief Asynchronously map a part of a file in memory.
+ * @param f The file to map.
+ * @param rule The rule to apply to the map.
+ * @param offset The offset inside the file
+ * @param length The length of the memory to map
+ * @param filter_cb Callback called in the thread to validate the content of the map.
+ * @param map_cb Callback called in the main loop when the file has been successfully mapped.
+ * @param error_cb Callback called in the main loop when the file can't be mapped.
+ * @param data Unmodified user data passed to callbacks
+ * @return Pointer to the file if successful or NULL otherwise.
+ *
+ * The container of the Eio_File is the Eina_File.
+ */
+EAPI Eio_File *eio_file_map_new(Eina_File *f,
+ Eina_File_Populate rule,
+ unsigned long int offset,
+ unsigned long int length,
+ Eio_Filter_Map_Cb filter_cb,
+ Eio_Map_Cb map_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Eio_Eet Eio asynchronous API for Eet file.
+ * @ingroup Eio
+ *
+ * @brief This set of functions help in the asynchronous use of Eet
+ *
+ * @{
+ */
+
+/**
+ * @brief Open an eet file on disk, and returns a handle to it asynchronously.
+ * @param filename The file path to the eet file. eg: @c "/tmp/file.eet".
+ * @param mode The mode for opening. Either EET_FILE_MODE_READ,
+ * EET_FILE_MODE_WRITE or EET_FILE_MODE_READ_WRITE.
+ * @param eet_cb The callback to call when the file has been successfully opened.
+ * @param error_cb Callback called in the main loop when the file can't be opened.
+ * @param data Unmodified user data passed to callbacks
+ * @return NULL in case of a failure.
+ *
+ * This function calls eet_open() from another thread using Ecore_Thread.
+ */
+EAPI Eio_File *eio_eet_open(const char *filename,
+ Eet_File_Mode mode,
+ Eio_Eet_Open_Cb eet_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+/**
+ * @brief Close an eet file handle and flush pending writes asynchronously.
+ * @param ef A valid eet file handle.
+ * @param done_cb Callback called from the main loop when the file has been closed.
+ * @param error_cb Callback called in the main loop when the file can't be closed.
+ * @param data Unmodified user data passed to callbacks
+ * @return NULL in case of a failure.
+ *
+ * This function will call eet_close() from another thread by
+ * using Ecore_Thread. You should assume that the Eet_File is dead after this
+ * function is called.
+ */
+EAPI Eio_File *eio_eet_close(Eet_File *ef,
+ Eio_Done_Cb done_cb,
+ Eio_Eet_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief Sync content of an eet file handle, flushing pending writes asynchronously.
+ * @param ef A valid eet file handle.
+ * @param done_cb Callback called from the main loop when the file has been synced.
+ * @param error_cb Callback called in the main loop when the file can't be synced.
+ * @param data Unmodified user data passed to callbacks
+ * @return NULL in case of a failure.
+ *
+ * This function will call eet_sync() from another thread. As long as the done_cb or
+ * error_cb haven't be called, you must keep @p ef open.
+ */
+EAPI Eio_File *eio_eet_sync(Eet_File *ef,
+ Eio_Done_Cb done_cb,
+ Eio_Eet_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief Write a data structure from memory and store in an eet file
+ * using a cipher asynchronously.
+ * @param ef The eet file handle to write to.
+ * @param edd The data descriptor to use when encoding.
+ * @param name The key to store the data under in the eet file.
+ * @param cipher_key The key to use as cipher.
+ * @param write_data A pointer to the data structure to save and encode.
+ * @param compress Compression flags for storage.
+ * @param done_cb Callback called from the main loop when the data has been put in the Eet_File.
+ * @param error_cb Callback called in the main loop when the file can't be written.
+ * @param user_data Private data given to each callback.
+ * @return NULL in case of a failure.
+ */
+EAPI Eio_File *eio_eet_data_write_cipher(Eet_File *ef,
+ Eet_Data_Descriptor *edd,
+ const char *name,
+ const char *cipher_key,
+ void *write_data,
+ int compress,
+ Eio_Done_Int_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *user_data);
+
+/**
+ * @brief Read a data structure from an eet file and decodes it using a cipher asynchronously.
+ * @param ef The eet file handle to read from.
+ * @param edd The data descriptor handle to use when decoding.
+ * @param name The key the data is stored under in the eet file.
+ * @param cipher_key The key to use as cipher.
+ * @param done_cb Callback called from the main loop when the data has been read and decoded.
+ * @param error_cb Callback called in the main loop when the data can't be read.
+ * @param data Unmodified user data passed to callbacks
+ * @return NULL in case of a failure.
+ */
+EAPI Eio_File *eio_eet_data_read_cipher(Eet_File *ef,
+ Eet_Data_Descriptor *edd,
+ const char *name,
+ const char *cipher_key,
+ Eio_Done_ERead_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief Write image data to the named key in an eet file asynchronously.
+ * @param ef A valid eet file handle opened for writing.
+ * @param name Name of the entry. eg: "/base/file_i_want".
+ * @param cipher_key The key to use as cipher.
+ * @param write_data A pointer to the image pixel data.
+ * @param w The width of the image in pixels.
+ * @param h The height of the image in pixels.
+ * @param alpha The alpha channel flag.
+ * @param compress The compression amount.
+ * @param quality The quality encoding amount.
+ * @param lossy The lossiness flag.
+ * @param done_cb Callback called from the main loop when the data has been put in the Eet_File.
+ * @param error_cb Callback called in the main loop when the file can't be written.
+ * @param user_data Private data given to each callback.
+ * @return NULL in case of a failure.
+ */
+EAPI Eio_File *eio_eet_data_image_write_cipher(Eet_File *ef,
+ const char *name,
+ const char *cipher_key,
+ void *write_data,
+ unsigned int w,
+ unsigned int h,
+ int alpha,
+ int compress,
+ int quality,
+ int lossy,
+ Eio_Done_Int_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *user_data);
+
+/**
+ * @brief Read a specified entry from an eet file and return data
+ * @param ef A valid eet file handle opened for reading.
+ * @param name Name of the entry. eg: "/base/file_i_want".
+ * @param done_cb Callback called from the main loop when the data has been read.
+ * @param error_cb Callback called in the main loop when the data can't be read.
+ * @param data Unmodified user data passed to callbacks
+ * @return NULL in case of a failure.
+ */
+EAPI Eio_File *eio_eet_read_direct(Eet_File *ef,
+ const char *name,
+ Eio_Done_Data_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief Read a specified entry from an eet file and return data
+ * @param ef A valid eet file handle opened for reading.
+ * @param name Name of the entry. eg: "/base/file_i_want".
+ * @param cipher_key The key to use as cipher.
+ * @param done_cb Callback called from the main loop when the data has been read.
+ * @param error_cb Callback called in the main loop when the data can't be read.
+ * @param data Unmodified user data passed to callbacks
+ * @return NULL in case of a failure.
+ */
+EAPI Eio_File *eio_eet_read_cipher(Eet_File *ef,
+ const char *name,
+ const char *cipher_key,
+ Eio_Done_Read_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *data);
+
+/**
+ * @brief Write a specified entry to an eet file handle using a cipher.
+ * @param ef A valid eet file handle opened for writing.
+ * @param name Name of the entry. eg: "/base/file_i_want".
+ * @param write_data Pointer to the data to be stored.
+ * @param size Length in bytes in the data to be stored.
+ * @param compress Compression flags (1 == compress, 0 = don't compress).
+ * @param cipher_key The key to use as cipher.
+ * @param done_cb Callback called from the main loop when the data has been put in the Eet_File.
+ * @param error_cb Callback called in the main loop when the file can't be written.
+ * @param user_data Private data given to each callback.
+ * @return NULL in case of a failure.
+ */
+EAPI Eio_File *eio_eet_write_cipher(Eet_File *ef,
+ const char *name,
+ void *write_data,
+ int size,
+ int compress,
+ const char *cipher_key,
+ Eio_Done_Int_Cb done_cb,
+ Eio_Error_Cb error_cb,
+ const void *user_data);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup Eio_Monitor Eio file and directory monitoring API
+ * @ingroup Eio
+ *
+ * @brief These function monitor changes in directories and files
+ *
+ * These functions use the best available method to monitor changes on a specified directory
+ * or file. They send ecore events when changes occur, and they maintain internal refcounts to
+ * reduce resource consumption on duplicate monitor targets.
+ *
+ * @{
+ */
+
+EAPI extern int EIO_MONITOR_FILE_CREATED; /**< A new file was created in a watched directory */
+EAPI extern int EIO_MONITOR_FILE_DELETED; /**< A watched file was deleted, or a file in a watched directory was deleted */
+EAPI extern int EIO_MONITOR_FILE_MODIFIED; /**< A file was modified in a watched directory */
+EAPI extern int EIO_MONITOR_FILE_CLOSED; /**< A file was closed in a watched directory. This event is never sent on Windows and OSX */
+EAPI extern int EIO_MONITOR_DIRECTORY_CREATED; /**< A new directory was created in a watched directory */
+EAPI extern int EIO_MONITOR_DIRECTORY_DELETED; /**< A directory has been deleted: this can be either a watched directory or one of its subdirectories */
+EAPI extern int EIO_MONITOR_DIRECTORY_MODIFIED; /**< A directory has been modified in a watched directory */
+EAPI extern int EIO_MONITOR_DIRECTORY_CLOSED; /**< A directory has been closed in a watched directory. This event is never sent on Windows and OSX */
+EAPI extern int EIO_MONITOR_SELF_RENAME; /**< The monitored path has been renamed, an error could happen just after if the renamed path doesn't exist. This event is never sent on OSX */
+EAPI extern int EIO_MONITOR_SELF_DELETED; /**< The monitored path has been removed. This event is never sent on OSX */
+EAPI extern int EIO_MONITOR_ERROR; /**< During operation the monitor failed and will no longer work. eio_monitor_del must be called on it. */
+
+typedef struct _Eio_Monitor Eio_Monitor;
+
+typedef struct _Eio_Monitor_Error Eio_Monitor_Error;
+typedef struct _Eio_Monitor_Event Eio_Monitor_Event;
+
+struct _Eio_Monitor_Error
+{
+ Eio_Monitor *monitor;
+ int error;
+};
+
+struct _Eio_Monitor_Event
+{
+ Eio_Monitor *monitor;
+ const char *filename;
+};
+
+/**
+ * @brief Adds a file/directory to monitor (inotify mechanism)
+ * @param path file/directory to monitor
+ * @return NULL in case of a failure or a pointer to the monitor in case of
+ * success.
+ *
+ * This function will add the given path to its internal
+ * list of files to monitor. It utilizes the inotify mechanism
+ * introduced in kernel 2.6.13 for passive monitoring.
+ */
+EAPI Eio_Monitor *eio_monitor_add(const char *path);
+
+/**
+ * @brief Adds a file/directory to monitor
+ * @param path file/directory to monitor
+ * @return NULL in case of a failure or a pointer to the monitor in case of
+ * success.
+ * @warning Do NOT pass non-stringshared strings to this function!
+ * If you don't know what this means, use eio_monitor_add().
+ *
+ * This fuction is just like eio_monitor_add(), however the string passed by
+ * argument must be created using eina_stringshare_add().
+ */
+EAPI Eio_Monitor *eio_monitor_stringshared_add(const char *path);
+
+/**
+ * @brief Deletes a path from the “watched” list
+ * @param monitor The Eio_Monitor you want to stop watching.
+ * It can only be an Eio_Monitor returned to you from calling
+ * eio_monitor_add() or eio_monitor_stringshared_add()
+ */
+EAPI void eio_monitor_del(Eio_Monitor *monitor);
+
+/**
+ * @brief returns the path being watched by the given
+ * Eio_Monitor.
+ * @param monitor Eio_Monitor to return the path of
+ * @return The stringshared path belonging to @p monitor
+ */
+EAPI const char *eio_monitor_path_get(Eio_Monitor *monitor);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/lib/eio/eio_job.c b/src/lib/eio/eio_job.c
new file mode 100644
index 0000000000..e9fb2f795f
--- /dev/null
+++ b/src/lib/eio/eio_job.c
@@ -0,0 +1,586 @@
+/* EIO - EFL data type library
+ * Copyright (C) 2016 Enlightenment Developers:
+ * Lauro Moura <lauromoura@expertisesolutions.com.br>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library;
+ * if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+
+#include <Eo.h>
+#include "Eio.h"
+#include "eio_job_private.h"
+
+typedef Eio_File* (*Eio_Job_Direct_Ls_Func)(const char *path, Eio_Filter_Direct_Cb, Eio_Main_Direct_Cb, Eio_Done_Cb, Eio_Error_Cb, const void *data);
+
+typedef struct _Job_Closure Job_Closure;
+struct _Job_Closure
+{
+ Eo *object;
+ Eio_Job_Data *pdata;
+ Eina_Promise_Owner *promise;
+ Eio_File *file;
+ Eina_Bool delete_me;
+ void *delayed_arg;
+ Eio_Job_Direct_Ls_Func direct_func; // Used when dispatching direct ls funcs.
+};
+
+/* Helper functions */
+
+static Job_Closure *
+_job_closure_create(Eo *obj, Eio_Job_Data *pdata, Eina_Promise_Owner *owner)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(obj, NULL);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(pdata, NULL);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(owner, NULL);
+
+ Job_Closure *closure = malloc(sizeof(Job_Closure));
+
+ if (!closure)
+ {
+ EINA_LOG_CRIT("Failed to allocate memory.");
+ return 0;
+ }
+
+ closure->object = eo_ref(obj);
+ closure->pdata = pdata;
+ closure->promise = owner;
+ closure->file = NULL; // Will be set once the Eio operation is under way
+ closure->delete_me = EINA_FALSE;
+ closure->delayed_arg = NULL;
+ closure->direct_func = NULL;
+
+ pdata->operations = eina_list_prepend(pdata->operations, closure);
+
+ return closure;
+}
+
+static void
+_job_closure_del(Job_Closure *closure)
+{
+ EINA_SAFETY_ON_NULL_RETURN(closure);
+ Eio_Job_Data *pdata = closure->pdata;
+ if (pdata)
+ pdata->operations = eina_list_remove(pdata->operations, closure);
+
+ eo_unref(closure->object);
+
+ if (closure->delayed_arg)
+ free(closure->delayed_arg);
+
+ free(closure);
+}
+
+static void
+_file_error_cb(void *data, Eio_File *handler EINA_UNUSED, int error)
+{
+ Job_Closure *operation = data;
+
+ EINA_SAFETY_ON_NULL_RETURN(operation);
+ EINA_SAFETY_ON_NULL_RETURN(operation->promise);
+
+ eina_promise_owner_error_set(operation->promise, error);
+
+ _job_closure_del(operation);
+}
+
+/* Basic listing callbacks */
+
+static Eina_Bool
+_file_ls_filter_cb_helper(const Eo_Event_Description *event, void *data, const char *file)
+{
+ Job_Closure *operation = data;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(operation, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(operation->pdata, EINA_FALSE);
+
+ Eio_Filter_Name_Data* event_info = malloc(sizeof(Eio_Filter_Name_Data));
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(event_info, EINA_FALSE);
+
+ event_info->file = file;
+ event_info->filter = EINA_FALSE;
+
+ eo_event_callback_call(operation->pdata->object, event, event_info);
+
+ Eina_Bool filter = event_info->filter;
+
+ free(event_info);
+
+ return filter;
+}
+
+static Eina_Bool
+_file_ls_filter_xattr_cb(void *data, Eio_File *handler EINA_UNUSED, const char *file)
+{
+ return _file_ls_filter_cb_helper(EIO_JOB_EVENT_XATTR, data, file);
+}
+
+static Eina_Bool
+_file_ls_filter_named_cb(void *data, Eio_File *handler EINA_UNUSED, const char *file)
+{
+ return _file_ls_filter_cb_helper(EIO_JOB_EVENT_FILTER_NAME, data, file);
+}
+
+static void
+_file_ls_main_cb(void *data, Eio_File *handler EINA_UNUSED, const char *file)
+{
+ Job_Closure *operation = data;
+ EINA_SAFETY_ON_NULL_RETURN(operation);
+ EINA_SAFETY_ON_NULL_RETURN(operation->promise);
+
+ eina_promise_owner_progress(operation->promise, (void*)file);
+}
+
+static void
+_file_done_cb(void *data, Eio_File *handler EINA_UNUSED)
+{
+ Job_Closure *operation = data;
+
+ EINA_SAFETY_ON_NULL_RETURN(operation);
+ EINA_SAFETY_ON_NULL_RETURN(operation->promise);
+
+ // Placeholder value. We just want the callback to be called.
+ Eina_Bool result = EINA_TRUE;
+ eina_promise_owner_value_set(operation->promise, &result, NULL);
+
+ _job_closure_del(operation);
+}
+
+static void
+_free_xattr_data(Eio_Xattr_Data *value)
+{
+ EINA_SAFETY_ON_NULL_RETURN(value);
+ if (value->data)
+ free((void*)value->data);
+}
+
+static void
+_file_done_data_cb(void *data, Eio_File *handler EINA_UNUSED, const char *attr_data, unsigned int size)
+{
+ Job_Closure *operation = data;
+ Eio_Xattr_Data *ret_data = NULL;
+
+ EINA_SAFETY_ON_NULL_RETURN(operation);
+ EINA_SAFETY_ON_NULL_RETURN(operation->promise);
+
+ ret_data = malloc(sizeof(Eio_Xattr_Data));
+
+ if (!ret_data)
+ {
+ EINA_LOG_CRIT("Failed to create promise result data.");
+ return;
+ }
+
+
+ ret_data->data = calloc(sizeof(char), size + 1);
+ strcpy((char*)ret_data->data, attr_data);
+ ret_data->size = size;
+
+ eina_promise_owner_value_set(operation->promise, ret_data, (Eina_Promise_Free_Cb)&_free_xattr_data);
+
+ free(ret_data);
+
+ _job_closure_del(operation);
+}
+
+/* Direct listing callbacks */
+
+static Eina_Bool
+_file_direct_ls_filter_cb(void *data, Eio_File *handle EINA_UNUSED, const Eina_File_Direct_Info *info)
+{
+ Job_Closure *operation = data;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(operation, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(operation->pdata, EINA_FALSE);
+
+ Eio_Filter_Direct_Data* event_info = malloc(sizeof(Eio_Filter_Direct_Data));
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(event_info, EINA_FALSE);
+
+ event_info->info = info;
+ event_info->filter = EINA_FALSE;
+
+ eo_event_callback_call(operation->pdata->object, EIO_JOB_EVENT_FILTER_DIRECT, event_info);
+
+ Eina_Bool filter = event_info->filter;
+
+ free(event_info);
+
+ return filter;
+}
+
+static void
+_file_direct_ls_main_cb(void *data, Eio_File *handler EINA_UNUSED, const Eina_File_Direct_Info *info)
+{
+ Job_Closure *operation = data;
+ EINA_SAFETY_ON_NULL_RETURN(operation);
+ EINA_SAFETY_ON_NULL_RETURN(operation->promise);
+
+ eina_promise_owner_progress(operation->promise, (void*)info);
+}
+
+static void
+_ls_direct_notify_start(void* data, Eina_Promise_Owner *promise)
+{
+ Job_Closure *operation_data = (Job_Closure*)data;
+ char* path = operation_data->delayed_arg;
+
+ Eio_File *handle = operation_data->direct_func(path,
+ _file_direct_ls_filter_cb,
+ _file_direct_ls_main_cb,
+ _file_done_cb,
+ _file_error_cb,
+ operation_data);
+ operation_data->file = handle;
+
+ promise->progress_notify = NULL;
+}
+
+static void
+_free_notify_start_data(void *data)
+{
+ Job_Closure *operation_data = (Job_Closure*)data;
+ if (!operation_data->delayed_arg)
+ return;
+ free(operation_data->delayed_arg);
+ operation_data->delayed_arg = NULL;
+}
+
+static void
+_ls_notify_start(void *data, Eina_Promise_Owner* promise)
+{
+ Job_Closure *operation_data = (Job_Closure*)data;
+ char* path = operation_data->delayed_arg;
+
+ Eio_File *handle = eio_file_ls(path,
+ _file_ls_filter_named_cb,
+ _file_ls_main_cb,
+ _file_done_cb,
+ _file_error_cb,
+ operation_data);
+ operation_data->file = handle;
+
+ promise->progress_notify = NULL; // Don't ever think about calling me again...
+}
+
+static void
+_xattr_notify_start(void *data, Eina_Promise_Owner *promise)
+{
+ Job_Closure *operation_data = (Job_Closure*)data;
+ char* path = operation_data->delayed_arg;
+
+ Eio_File *handle = eio_file_xattr(path,
+ _file_ls_filter_xattr_cb,
+ _file_ls_main_cb,
+ _file_done_cb,
+ _file_error_cb,
+ operation_data);
+ operation_data->file = handle;
+
+ promise->progress_notify = NULL; // Don't ever think about calling me again...
+}
+
+static void
+_job_direct_ls_helper(Eio_Job_Direct_Ls_Func ls_func,
+ Eo* obj,
+ Eio_Job_Data *pd,
+ const char *path,
+ Eina_Promise_Owner *promise)
+{
+ Job_Closure *operation_data = _job_closure_create(obj, pd, promise);
+
+ if (!operation_data)
+ {
+ EINA_LOG_CRIT("Failed to create eio job operation data.");
+ return;
+ }
+
+ operation_data->delayed_arg = (char*)calloc(sizeof(char), strlen(path) + 1);
+ strcpy(operation_data->delayed_arg, path);
+
+ operation_data->direct_func = ls_func;
+
+ eina_promise_owner_progress_notify(promise,
+ _ls_direct_notify_start,
+ operation_data,
+ _free_notify_start_data);
+}
+
+/* Method implementations */
+
+void
+_eio_job_file_direct_ls(Eo *obj,
+ Eio_Job_Data *pd,
+ const char *path,
+ Eina_Promise_Owner *promise)
+{
+ _job_direct_ls_helper(&eio_file_direct_ls, obj, pd, path, promise);
+}
+
+void
+_eio_job_file_stat_ls(Eo *obj,
+ Eio_Job_Data *pd,
+ const char *path,
+ Eina_Promise_Owner *promise)
+{
+ _job_direct_ls_helper(&eio_file_stat_ls, obj, pd, path, promise);
+}
+
+void
+_eio_job_dir_stat_ls(Eo *obj,
+ Eio_Job_Data *pd,
+ const char *path,
+ Eina_Promise_Owner *promise)
+{
+ _job_direct_ls_helper(&eio_dir_stat_ls, obj, pd, path, promise);
+}
+
+void
+_eio_job_dir_direct_ls(Eo *obj EINA_UNUSED,
+ Eio_Job_Data *pd EINA_UNUSED,
+ const char *path,
+ Eina_Promise_Owner *promise EINA_UNUSED)
+{
+ // Had to add the cast as dir_direct differs in the filter callback constness of one of
+ // its arguments.
+ _job_direct_ls_helper((Eio_Job_Direct_Ls_Func)&eio_dir_direct_ls, obj, pd, path, promise);
+}
+
+void
+_eio_job_file_ls(Eo *obj,
+ Eio_Job_Data *pd,
+ const char *path,
+ Eina_Promise_Owner *promise)
+{
+ Job_Closure *operation_data = _job_closure_create(obj, pd, promise);
+
+ if (!operation_data)
+ {
+ EINA_LOG_CRIT("Failed to create eio job operation data.");
+ return;
+ }
+
+ operation_data->delayed_arg = (char*)calloc(sizeof(char), strlen(path) + 1);
+ strcpy(operation_data->delayed_arg, path);
+
+ eina_promise_owner_progress_notify(promise,
+ _ls_notify_start,
+ operation_data,
+ _free_notify_start_data);
+}
+
+/* Stat function */
+
+static void
+_file_stat_done_cb(void *data, Eio_File *handle EINA_UNUSED, const Eina_Stat *stat)
+{
+ Job_Closure *operation = data;
+
+ EINA_SAFETY_ON_NULL_RETURN(operation);
+ EINA_SAFETY_ON_NULL_RETURN(operation->promise);
+
+ // Placeholder value. We just want the callback to be called.
+ eina_promise_owner_value_set(operation->promise, &stat, NULL);
+
+ _job_closure_del(operation);
+}
+
+void
+_eio_job_file_direct_stat(Eo *obj,
+ Eio_Job_Data *pd,
+ const char *path,
+ Eina_Promise_Owner *promise)
+{
+ Job_Closure *operation_data = _job_closure_create(obj, pd, promise);
+
+ if (!operation_data)
+ {
+ EINA_LOG_CRIT("Failed to create eio job operation data.");
+ return;
+ }
+
+ Eio_File *handle = eio_file_direct_stat(path,
+ _file_stat_done_cb,
+ _file_error_cb,
+ operation_data);
+ operation_data->file = handle;
+}
+
+/* eXtended attribute manipulation */
+
+void
+_eio_job_file_xattr(Eo *obj,
+ Eio_Job_Data *pd,
+ const char *path,
+ Eina_Promise_Owner *promise)
+{
+ Job_Closure *operation_data = _job_closure_create(obj, pd, promise);
+
+ if (!operation_data)
+ {
+ EINA_LOG_CRIT("Failed to create eio job operation data.");
+ return;
+ }
+
+ operation_data->delayed_arg = (char*)calloc(sizeof(char), strlen(path) + 1);
+ strcpy(operation_data->delayed_arg, path);
+
+ eina_promise_owner_progress_notify(promise,
+ _xattr_notify_start,
+ operation_data,
+ _free_notify_start_data);
+}
+
+void
+_eio_job_file_xattr_set(Eo *obj,
+ Eio_Job_Data *pd,
+ const char *path,
+ const char *attribute,
+ const char *xattr_data,
+ unsigned int xattr_size,
+ Eina_Xattr_Flags flags,
+ Eina_Promise_Owner *promise)
+{
+ Job_Closure *operation_data = _job_closure_create(obj, pd, promise);
+
+ if (!operation_data)
+ {
+ EINA_LOG_CRIT("Failed to create eio job operation data.");
+ return;
+ }
+
+ Eio_File *handle = eio_file_xattr_set(path,
+ attribute,
+ xattr_data,
+ xattr_size,
+ flags,
+ _file_done_cb,
+ _file_error_cb,
+ operation_data);
+ operation_data->file = handle;
+}
+
+void
+_eio_job_file_xattr_get(Eo *obj,
+ Eio_Job_Data *pd,
+ const char *path,
+ const char *attribute,
+ Eina_Promise_Owner *promise)
+{
+ Job_Closure *operation_data = _job_closure_create(obj, pd, promise);
+
+ if (!operation_data)
+ {
+ EINA_LOG_CRIT("Failed to create eio job operation data.");
+ return;
+ }
+
+ Eio_File *handle = eio_file_xattr_get(path,
+ attribute,
+ _file_done_data_cb,
+ _file_error_cb,
+ operation_data);
+ operation_data->file = handle;
+}
+
+/* Eina_File mapping and handling. */
+
+static void
+_file_open_open_cb(void *data, Eio_File *handler EINA_UNUSED, Eina_File *file)
+{
+ Job_Closure *operation = data;
+ EINA_SAFETY_ON_NULL_RETURN(operation);
+ EINA_SAFETY_ON_NULL_RETURN(operation->promise);
+ // FIXME On promise composition, a successfully open file would leak open
+ // another promise in the composition fails as there is no free/close
+ // function. Calling eina_file_close blocks on a lock_take call on a
+ // field of the Eina_File file.
+ eina_promise_owner_value_set(operation->promise, &file, NULL);
+
+ _job_closure_del(operation);
+}
+
+void
+_eio_job_file_open(Eo *obj,
+ Eio_Job_Data *pd,
+ const char *path,
+ Eina_Bool shared,
+ Eina_Promise_Owner *promise)
+{
+ Job_Closure *operation_data = _job_closure_create(obj, pd, promise);
+
+ if (!operation_data)
+ {
+ EINA_LOG_CRIT("Failed to create eio job operation data.");
+ return;
+ }
+
+ Eio_File *handle = eio_file_open(path, shared, _file_open_open_cb, _file_error_cb, operation_data);
+ operation_data->file = handle;
+}
+
+
+static
+void _file_close_done_cb(void *data, Eio_File *handler EINA_UNUSED)
+{
+ EINA_SAFETY_ON_NULL_RETURN(data);
+ Job_Closure *operation = data;
+ Eina_Bool result = EINA_TRUE;
+ eina_promise_owner_value_set(operation->promise, &result, NULL);
+
+ _job_closure_del(operation);
+}
+void _eio_job_file_close(Eo *obj,
+ Eio_Job_Data *pd,
+ Eina_File *file,
+ Eina_Promise_Owner *promise)
+{
+ Job_Closure *operation_data = _job_closure_create(obj, pd, promise);
+
+ if (!operation_data)
+ {
+ EINA_LOG_CRIT("Failed to create eio job operation data.");
+ return;
+ }
+
+ Eio_File *handle = eio_file_close(file, _file_close_done_cb, _file_error_cb, operation_data);
+ operation_data->file = handle;
+}
+
+void _eio_job_cancel_all(Eo *obj EINA_UNUSED, Eio_Job_Data *pd EINA_UNUSED)
+{
+ printf("%s called.\n", __FUNCTION__);
+}
+
+Eo_Base * _eio_job_eo_base_constructor(Eo *obj, Eio_Job_Data *pd EINA_UNUSED)
+{
+ obj = eo_constructor(eo_super(obj, EIO_JOB_CLASS));
+
+ pd->object = obj;
+ pd->operations = NULL;
+
+ return obj;
+}
+
+void _eio_job_eo_base_destructor(Eo *obj, Eio_Job_Data *pd EINA_UNUSED)
+{
+ eo_destructor(eo_super(obj, EIO_JOB_CLASS));
+}
+
+#include "eio_job.eo.c"
diff --git a/src/lib/eio/eio_job.eo b/src/lib/eio/eio_job.eo
new file mode 100644
index 0000000000..3a12d23e92
--- /dev/null
+++ b/src/lib/eio/eio_job.eo
@@ -0,0 +1,152 @@
+import eina_types;
+
+struct Eio.Data
+{
+ [[A structure to handle arbitrary data to be sent over Promises.]]
+ data: void *;
+ size: uint;
+}
+
+struct Eio.Filter.Direct.Data
+{
+ info: const(Eina.File.Direct.Info)*;
+ filter: bool;
+}
+
+struct Eio.Filter.Name.Data
+{
+ file: const(char)*;
+ filter: bool;
+}
+
+struct Eio.Xattr.Data
+{
+ data: const(char)*;
+ size: uint;
+}
+
+class Eio.Job (Eo.Base)
+{
+ [[Class representing an asynchronous file operation.]]
+
+ legacy_prefix: null;
+
+ methods {
+
+ // Listing operations
+ file_ls {
+ [[Lists entries in a given path.]]
+ params {
+ @in path: const(char)*;
+ @inout promise: promise<int, const(char)*>;
+ }
+ }
+
+ file_direct_ls {
+ [[Lists entries in a given path with more information.]]
+ params {
+ @in path: const(char)*;
+ @inout promise: promise<int, const(Eina_File_Direct_Info)*>;
+ }
+ }
+
+ file_stat_ls {
+ [[Lists entries in a given path with stat information.]]
+ params {
+ @in path: const(char)*;
+ @inout promise: promise<int, const(Eina_File_Direct_Info)*>;
+ }
+ }
+
+ dir_stat_ls {
+ [[Recursively list the directory content and its sub content.]]
+ params {
+ @in path: const(char)*;
+ @inout promise: promise<int, const(Eina_File_Direct_Info)*>;
+ }
+ }
+
+ dir_direct_ls {
+ [[Recursively list the directory content and its sub content.]]
+ params {
+ @in path: const(char)*;
+ @inout promise: promise<int, const(Eina_File_Direct_Info)*>;
+ }
+ }
+
+ file_direct_stat {
+ [[Get stat info on a given file/directory.]]
+ params {
+ @in path: const(char)*;
+ @inout promise: promise<const(Eina_Stat)*>; //TODO Change to a delayed promise.
+ }
+ }
+
+ // Extended attributes
+
+ file_xattr {
+ [[Lists all extended attributes asynchronously.]]
+ params {
+ @in path: const(char)*;
+ @inout promise: promise<int, const(char)*>;
+ }
+ }
+
+ file_xattr_set {
+ [[Sets a given extended attribute.]]
+ params {
+ @in path: const(char)*;
+ @in attribute: const(char)*;
+ @in xattr_data: const(char)*;
+ @in xattr_size: uint;
+ @in flags: Eina.Xattr.Flags;
+ @inout promise: promise<int>;
+ }
+ }
+
+ file_xattr_get {
+ [[Sets a given extended attribute.]]
+ params {
+ @in path: const(char)*;
+ @in attribute: const(char)*;
+ @inout promise: promise<Eio.Xattr.Data*>;
+ }
+ }
+
+ // helper api
+ file_open {
+ [[Opens a file.
+
+ The fulfilled value in the promise will be the Eina.File*.]]
+ params {
+ @in path: const(char)*;
+ @in shared: bool;
+ @inout promise: promise<Eina.File*>;
+ }
+ }
+ file_close {
+ [[Closes an open Eina.File.]]
+ params {
+ @in file: Eina.File*;
+ // Here we're just interested whether the promise was fullfilled or not. No value needed.
+ @inout promise: promise<int>;
+ }
+ }
+ cancel_all {
+ [[Cancels all pending operations on this job.]]
+ params {
+ // Shall we need some promise here?
+ }
+ }
+ }
+ events {
+ filter,name: Eio.Filter.Name.Data;
+ filter,direct: Eio.Filter.Direct.Data;
+ xattr: Eio.Filter.Name.Data;
+ }
+
+ implements {
+ Eo.Base.constructor;
+ Eo.Base.destructor;
+ }
+}
diff --git a/src/lib/eio/eio_job_private.h b/src/lib/eio/eio_job_private.h
new file mode 100644
index 0000000000..26a2a5a9b6
--- /dev/null
+++ b/src/lib/eio/eio_job_private.h
@@ -0,0 +1,12 @@
+#ifndef _EIO_FILE_PRIVATE_H
+#define _EIO_FILE_PRIVATE_H
+
+typedef struct _Eio_Job_Data Eio_Job_Data;
+
+struct _Eio_Job_Data
+{
+ Eo *object;
+ Eina_List *operations;
+};
+
+#endif
diff --git a/src/lib/eio/eio_sentry.c b/src/lib/eio/eio_sentry.c
new file mode 100644
index 0000000000..c0bf7b1d49
--- /dev/null
+++ b/src/lib/eio/eio_sentry.c
@@ -0,0 +1,166 @@
+/* EIO - EFL data type library
+ * Copyright (C) 2016 Enlightenment Developers:
+ * Lauro Moura <lauromoura@expertisesolutions.com.br>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library;
+ * if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+
+#include <Eo.h>
+#include "Ecore.h"
+#include "Eio.h"
+#include "eio_sentry_private.h"
+
+
+static const Eo_Event_Description*
+_translate_event(int input_event)
+{
+ if (input_event == EIO_MONITOR_FILE_CREATED)
+ return EIO_SENTRY_EVENT_FILE_CREATED;
+ else if (input_event == EIO_MONITOR_FILE_DELETED)
+ return EIO_SENTRY_EVENT_FILE_DELETED;
+ else if (input_event == EIO_MONITOR_FILE_MODIFIED)
+ return EIO_SENTRY_EVENT_FILE_MODIFIED;
+ else if (input_event == EIO_MONITOR_FILE_CLOSED)
+ return EIO_SENTRY_EVENT_FILE_CLOSED;
+ else if (input_event == EIO_MONITOR_DIRECTORY_CREATED)
+ return EIO_SENTRY_EVENT_DIRECTORY_CREATED;
+ else if (input_event == EIO_MONITOR_DIRECTORY_DELETED)
+ return EIO_SENTRY_EVENT_DIRECTORY_DELETED;
+ else if (input_event == EIO_MONITOR_DIRECTORY_MODIFIED)
+ return EIO_SENTRY_EVENT_DIRECTORY_MODIFIED;
+ else if (input_event == EIO_MONITOR_DIRECTORY_CLOSED)
+ return EIO_SENTRY_EVENT_DIRECTORY_CLOSED;
+ else if (input_event == EIO_MONITOR_SELF_RENAME)
+ return EIO_SENTRY_EVENT_SELF_RENAME;
+ else if (input_event == EIO_MONITOR_SELF_DELETED)
+ return EIO_SENTRY_EVENT_SELF_DELETED;
+ else if (input_event == EIO_MONITOR_ERROR)
+ return EIO_SENTRY_EVENT_ERROR;
+ else
+ return NULL;
+}
+
+static unsigned char
+_handle_event(void *data, int type, void *event)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(data, ECORE_CALLBACK_PASS_ON);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(event, ECORE_CALLBACK_PASS_ON);
+
+ const Eo_Event_Description* translated_event = _translate_event(type);
+ Eio_Sentry_Data *pd = (Eio_Sentry_Data *)data;
+ Eio_Monitor_Event *monitor_event = (Eio_Monitor_Event *)event;
+
+ Eio_Sentry_Event *event_info = malloc(sizeof(Eio_Sentry_Event));
+ EINA_SAFETY_ON_NULL_RETURN_VAL(event_info, ECORE_CALLBACK_PASS_ON);
+
+ event_info->source = eio_monitor_path_get(monitor_event->monitor);
+ event_info->trigger = monitor_event->filename;
+
+ eo_event_callback_call(pd->object, translated_event, event_info);
+
+ // If event was error, we must delete the monitor.
+ if (type == EIO_MONITOR_ERROR)
+ eina_hash_del(pd->targets, event_info->source, NULL);
+
+ free(event_info);
+
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+static void
+_initialize_handlers(Eio_Sentry_Data *pd)
+{
+ EINA_SAFETY_ON_NULL_RETURN(pd);
+
+ ecore_event_handler_add(EIO_MONITOR_FILE_CREATED, _handle_event, pd);
+ ecore_event_handler_add(EIO_MONITOR_FILE_DELETED, _handle_event, pd);
+ ecore_event_handler_add(EIO_MONITOR_FILE_MODIFIED, _handle_event, pd);
+ ecore_event_handler_add(EIO_MONITOR_FILE_CLOSED, _handle_event, pd);
+
+ ecore_event_handler_add(EIO_MONITOR_DIRECTORY_CREATED, _handle_event, pd);
+ ecore_event_handler_add(EIO_MONITOR_DIRECTORY_DELETED, _handle_event, pd);
+ ecore_event_handler_add(EIO_MONITOR_DIRECTORY_MODIFIED, _handle_event, pd);
+ ecore_event_handler_add(EIO_MONITOR_DIRECTORY_CLOSED, _handle_event, pd);
+
+ ecore_event_handler_add(EIO_MONITOR_SELF_RENAME, _handle_event, pd);
+ ecore_event_handler_add(EIO_MONITOR_SELF_DELETED, _handle_event, pd);
+ ecore_event_handler_add(EIO_MONITOR_ERROR, _handle_event, pd);
+
+ pd->handlers_initialized = EINA_TRUE;
+}
+
+Eina_Bool
+_eio_sentry_add(Eo *obj EINA_UNUSED, Eio_Sentry_Data *pd, const char *path)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(path, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(pd, EINA_FALSE);
+
+ if (!pd->handlers_initialized)
+ _initialize_handlers(pd);
+
+ if (eina_hash_find(pd->targets, path))
+ return EINA_TRUE;
+
+ Eio_Monitor *monitor = eio_monitor_add(path);
+
+ if (!monitor)
+ {
+ EINA_LOG_ERR("Failed to create monitor.");
+ return EINA_FALSE;
+ }
+
+ if (!eina_hash_add(pd->targets, path, monitor))
+ {
+ EINA_LOG_ERR("Failed to register monitor.");
+ eio_monitor_del(monitor);
+ return EINA_FALSE;
+ }
+
+ return EINA_TRUE;
+}
+
+void
+_eio_sentry_del(Eo *obj EINA_UNUSED, Eio_Sentry_Data *pd, const char *path)
+{
+ EINA_SAFETY_ON_NULL_RETURN(path);
+ EINA_SAFETY_ON_NULL_RETURN(pd);
+
+ eina_hash_del(pd->targets, path, NULL);
+}
+
+Eo_Base * _eio_sentry_eo_base_constructor(Eo *obj, Eio_Sentry_Data *pd)
+{
+ obj = eo_constructor(eo_super(obj, EIO_SENTRY_CLASS));
+
+ pd->object = obj;
+ pd->targets = eina_hash_string_small_new((Eina_Free_Cb)&eio_monitor_del);
+ pd->handlers_initialized = EINA_FALSE;
+
+ return obj;
+}
+
+void _eio_sentry_eo_base_destructor(Eo *obj, Eio_Sentry_Data *pd)
+{
+ eina_hash_free(pd->targets);
+
+ eo_destructor(eo_super(obj, EIO_SENTRY_CLASS));
+}
+
+#include "eio_sentry.eo.c"
diff --git a/src/lib/eio/eio_sentry.eo b/src/lib/eio/eio_sentry.eo
new file mode 100644
index 0000000000..e9b39ddc86
--- /dev/null
+++ b/src/lib/eio/eio_sentry.eo
@@ -0,0 +1,49 @@
+import eina_types;
+
+struct Eio.Sentry.Event
+{
+ [[Wraps the data about a monitor event on a file.]]
+ trigger: const(char)*; [[The cause of the event.]]
+ source: const(char)*; [[The original monitored path.]]
+}
+
+class Eio.Sentry (Eo.Base)
+{
+ [[Monitors files and directories for changes.]]
+
+ legacy_prefix: null;
+
+ methods {
+ add {
+ [[Adds a new path to the list of monitored paths.]]
+ params {
+ @in path: const(char)*;
+ }
+ return : bool;
+ }
+ del {
+ [[Removes the given path from the monitored list.]]
+ params {
+ @in path: const(char)*;
+ }
+ }
+ }
+ events {
+ file,created: Eio.Sentry.Event;
+ file,deleted: Eio.Sentry.Event;
+ file,modified: Eio.Sentry.Event;
+ file,closed: Eio.Sentry.Event;
+ directory,created: Eio.Sentry.Event;
+ directory,deleted: Eio.Sentry.Event;
+ directory,modified: Eio.Sentry.Event;
+ directory,closed: Eio.Sentry.Event;
+ self,rename: Eio.Sentry.Event;
+ self,deleted: Eio.Sentry.Event;
+ error: Eio.Sentry.Event;
+ }
+
+ implements {
+ Eo.Base.constructor;
+ Eo.Base.destructor;
+ }
+}
diff --git a/src/lib/eio/eio_sentry_private.h b/src/lib/eio/eio_sentry_private.h
new file mode 100644
index 0000000000..ade192fdf7
--- /dev/null
+++ b/src/lib/eio/eio_sentry_private.h
@@ -0,0 +1,13 @@
+#ifndef _EIO_SENTRY_PRIVATE_H
+#define _EIO_SENTRY_PRIVATE_H
+
+typedef struct _Eio_Sentry_Data Eio_Sentry_Data;
+
+struct _Eio_Sentry_Data
+{
+ Eo *object;
+ Eina_Hash *targets;
+ Eina_Bool handlers_initialized;
+};
+
+#endif
diff --git a/src/lib/eo/eina_types.eot b/src/lib/eo/eina_types.eot
index 4114581227..9838212390 100644
--- a/src/lib/eo/eina_types.eot
+++ b/src/lib/eo/eina_types.eot
@@ -27,3 +27,11 @@ struct @extern Eina.Inarray;
type @extern Eina.Unicode: uint32;
struct @extern Eina.Value;
+
+struct @extern Eina.File.Direct.Info;
+
+enum Eina.Xattr.Flags {
+ insert, [[This is the default behaviour, it will either create or replace the extended attribute]]
+ replace, [[This will only succeed if the extended attribute previously existed]]
+ created [[This will only succeed if the extended attribute wasn't previously set]]
+} \ No newline at end of file
diff --git a/src/tests/eio/eio_suite.c b/src/tests/eio/eio_suite.c
index 39ce8f769a..10ff27d531 100644
--- a/src/tests/eio/eio_suite.c
+++ b/src/tests/eio/eio_suite.c
@@ -7,11 +7,14 @@
static const Efl_Test_Case etc[] = {
{"Eio_Monitor", eio_test_monitor},
+ {"Eio_Sentry", eio_test_sentry},
{"Eio Model", eio_model_test_file},
{"Eio Model Monitor", eio_model_test_monitor_add},
{"Eio File", eio_test_file},
+ {"Eio Job", eio_test_job},
#ifdef XATTR_TEST_DIR
{"Eio_Xattr", eio_test_xattr},
+ {"Eio Job Xattr", eio_test_job_xattr},
#endif
{NULL, NULL}
};
diff --git a/src/tests/eio/eio_suite.h b/src/tests/eio/eio_suite.h
index 170a060c73..cdecfd0f09 100644
--- a/src/tests/eio/eio_suite.h
+++ b/src/tests/eio/eio_suite.h
@@ -4,9 +4,12 @@
#include <check.h>
void eio_test_monitor(TCase *tc);
+void eio_test_sentry(TCase *tc);
void eio_model_test_file(TCase *tc);
void eio_model_test_monitor_add(TCase *tc);
void eio_test_file(TCase *tc);
+void eio_test_job(TCase *tc);
+void eio_test_job_xattr(TCase *tc);
void eio_test_xattr(TCase *tc);
#endif /* _EIO_SUITE_H */
diff --git a/src/tests/eio/eio_test_common.c b/src/tests/eio/eio_test_common.c
new file mode 100644
index 0000000000..711c5bfac7
--- /dev/null
+++ b/src/tests/eio/eio_test_common.c
@@ -0,0 +1,89 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "eio_suite.h"
+#include "eio_test_common.h"
+
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
+
+static const char *good_dirs[] =
+ {
+ "eio_file_ls_simple_dir",
+ "b."
+ };
+
+unsigned int default_rights = DEFAULT_RIGHTS;
+
+const char *files[] =
+ {
+ ".hidden_file",
+ "~$b@:-*$a!{}",
+ "$b$a",
+ "normal_file"
+ };
+
+Eina_Tmpstr*
+get_full_path(const char* tmpdirname, const char* filename)
+{
+ char full_path[PATH_MAX] = "";
+ eina_str_join(full_path, sizeof(full_path), '/', tmpdirname, filename);
+ return eina_tmpstr_add(full_path);
+}
+
+Eina_Tmpstr*
+get_eio_test_file_tmp_dir()
+{
+ Eina_Tmpstr *tmp_dir;
+
+ Eina_Bool created = eina_file_mkdtemp("EioFileTestXXXXXX", &tmp_dir);
+
+ if (!created)
+ {
+ return NULL;
+ }
+
+ return tmp_dir;
+}
+
+Eina_Tmpstr*
+create_test_dirs(Eina_Tmpstr *test_dirname)
+{
+ int i, fd;
+ int count = sizeof(good_dirs) / sizeof(const char *);
+ fail_if(test_dirname == NULL);
+
+ for (i = 0; i != count; ++i)
+ {
+ Eina_Tmpstr *dirname = get_full_path(test_dirname, good_dirs[i]);
+ fail_if(mkdir(dirname, default_rights) != 0);
+ eina_tmpstr_del(dirname);
+ }
+ count = sizeof(files) / sizeof(const char *);
+ for (i = 0; i != count; ++i)
+ {
+ Eina_Tmpstr *filename = get_full_path(test_dirname, files[i]);
+ fd = open(filename, O_RDWR | O_BINARY | O_CREAT, default_rights);
+ fail_if(fd < 0);
+ fail_if(close(fd) != 0);
+ eina_tmpstr_del(filename);
+ }
+ Eina_Tmpstr *nested_dirname = get_full_path(test_dirname, good_dirs[0]);
+ for (i = 0; i != count; ++i)
+ {
+ Eina_Tmpstr *filename = get_full_path(nested_dirname, files[i]);
+ fd = open(filename, O_RDWR | O_BINARY | O_CREAT, default_rights);
+ fail_if(fd < 0);
+ fail_if(close(fd) != 0);
+ eina_tmpstr_del(filename);
+ }
+ return nested_dirname;
+}
diff --git a/src/tests/eio/eio_test_common.h b/src/tests/eio/eio_test_common.h
new file mode 100644
index 0000000000..87d416486c
--- /dev/null
+++ b/src/tests/eio/eio_test_common.h
@@ -0,0 +1,16 @@
+#ifndef _EIO_TEST_COMMON_H
+#define _EIO_TEST_COMMON_H
+
+#include <Eina.h>
+
+#define DEFAULT_RIGHTS 0755;
+extern unsigned int default_rights;
+extern const char *files[];
+
+Eina_Tmpstr* get_full_path(const char* tmpdirname, const char* filename);
+
+Eina_Tmpstr* get_eio_test_file_tmp_dir();
+
+Eina_Tmpstr* create_test_dirs(Eina_Tmpstr *test_dirname);
+
+#endif \ No newline at end of file
diff --git a/src/tests/eio/eio_test_file.c b/src/tests/eio/eio_test_file.c
index d4c71cd11d..b9eedefb96 100644
--- a/src/tests/eio/eio_test_file.c
+++ b/src/tests/eio/eio_test_file.c
@@ -13,25 +13,13 @@
#include <Eio.h>
#include "eio_suite.h"
+#include "eio_test_common.h"
#ifndef O_BINARY
# define O_BINARY 0
#endif
-static unsigned int default_rights = 0755;
static int test_count = 0;
-static const char *good_dirs[] =
- {
- "eio_file_ls_simple_dir",
- "b."
- };
-static const char *files[] =
- {
- ".hidden_file",
- "~$b@:-*$a!{}",
- "$b$a",
- "normal_file"
- };
static Eina_Bool
_filter_cb(void *data EINA_UNUSED, Eio_File *handler EINA_UNUSED, const char *file)
@@ -127,63 +115,6 @@ _open_done_cb(void *data, Eio_File *handler EINA_UNUSED, Eina_File *file)
ecore_main_loop_quit();
}
-Eina_Tmpstr*
-get_full_path(const char* tmpdirname, const char* filename)
-{
- char full_path[PATH_MAX] = "";
- eina_str_join(full_path, sizeof(full_path), '/', tmpdirname, filename);
- return eina_tmpstr_add(full_path);
-}
-
-Eina_Tmpstr*
-get_eio_test_file_tmp_dir()
-{
- Eina_Tmpstr *tmp_dir;
-
- Eina_Bool created = eina_file_mkdtemp("EioFileTestXXXXXX", &tmp_dir);
-
- if (!created)
- {
- return NULL;
- }
-
- return tmp_dir;
-}
-
-Eina_Tmpstr*
-create_test_dirs(Eina_Tmpstr *test_dirname)
-{
- int i, fd;
- int count = sizeof(good_dirs) / sizeof(const char *);
- fail_if(test_dirname == NULL);
-
- for (i = 0; i != count; ++i)
- {
- Eina_Tmpstr *dirname = get_full_path(test_dirname, good_dirs[i]);
- fail_if(mkdir(dirname, default_rights) != 0);
- eina_tmpstr_del(dirname);
- }
- count = sizeof(files) / sizeof(const char *);
- for (i = 0; i != count; ++i)
- {
- Eina_Tmpstr *filename = get_full_path(test_dirname, files[i]);
- fd = open(filename, O_RDWR | O_BINARY | O_CREAT, default_rights);
- fail_if(fd < 0);
- fail_if(close(fd) != 0);
- eina_tmpstr_del(filename);
- }
- Eina_Tmpstr *nested_dirname = get_full_path(test_dirname, good_dirs[0]);
- for (i = 0; i != count; ++i)
- {
- Eina_Tmpstr *filename = get_full_path(nested_dirname, files[i]);
- fd = open(filename, O_RDWR | O_BINARY | O_CREAT, default_rights);
- fail_if(fd < 0);
- fail_if(close(fd) != 0);
- eina_tmpstr_del(filename);
- }
- return nested_dirname;
-}
-
START_TEST(eio_file_test_ls)
{
int number_of_listed_files = 0, ret;
@@ -297,6 +228,7 @@ START_TEST(eio_file_test_file)
is_dir = EINA_FALSE;
eio_file_direct_stat(nested_filename, _stat_done_cb, _error_cb, &is_dir);
ecore_main_loop_begin();
+ default_rights = DEFAULT_RIGHTS;
test_count = 1;
eio_file_move(nested_filename, new_filename, _progress_cb, _done_cb,
diff --git a/src/tests/eio/eio_test_job.c b/src/tests/eio/eio_test_job.c
new file mode 100644
index 0000000000..1751436d02
--- /dev/null
+++ b/src/tests/eio/eio_test_job.c
@@ -0,0 +1,287 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Ecore.h>
+#include <Ecore_File.h>
+#include <Eio.h>
+
+#include "eio_suite.h"
+#include "eio_test_common.h"
+
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
+
+static int test_count = 0;
+
+static int DONE_CALLED = 0xdeadbeef;
+
+static void
+_filter_direct_cb(void *data EINA_UNUSED, const Eo_Event *event)
+{
+ Eio_Filter_Direct_Data *event_info = event->info;
+ char *last_slash = strrchr(event_info->info->path, '/');
+
+ //Check if it is a hidden file
+ if (last_slash != NULL && strlen(last_slash) > 1 && last_slash[1] == '.')
+ event_info->filter = EINA_FALSE;
+ else
+ event_info->filter = EINA_TRUE;
+}
+
+static void
+_main_direct_cb(void *data, const Eina_File_Direct_Info *info)
+{
+ int *number_of_listed_files = (int *)data;
+
+ fprintf(stderr, "Processing file:%s\n", info->path);
+ (*number_of_listed_files)++;
+}
+
+static void
+_filter_cb(void *data EINA_UNUSED, const Eo_Event *event)
+{
+ Eio_Filter_Name_Data *event_info = event->info;
+ char *last_slash = strrchr(event_info->file, '/');
+
+ //Check if it is a hidden file
+ if (last_slash != NULL && strlen(last_slash) > 1 && last_slash[1] == '.')
+ event_info->filter = EINA_FALSE;
+ else
+ event_info->filter = EINA_TRUE;
+}
+
+static void
+_main_cb(void *data, const char *file)
+{
+ int *number_of_listed_files = (int *)data;
+
+ fprintf(stderr, "Processing file:%s\n", file);
+ (*number_of_listed_files)++;
+}
+
+static void
+_done_cb(void *data, Eio_File *handler EINA_UNUSED)
+{
+ int *number_of_listed_files = (int *)data;
+ fail_if((*number_of_listed_files) != test_count);
+ *number_of_listed_files = DONE_CALLED;
+ ecore_main_loop_quit();
+}
+
+static void
+_error_cb(void *data EINA_UNUSED, Eina_Error *error)
+{
+ const char *msg = eina_error_msg_get(*error);
+ EINA_LOG_ERR("error: %s", msg);
+ ecore_main_loop_quit();
+}
+
+static void
+_open_done_cb(void *data, Eina_File **file)
+{
+ Eina_Bool *opened = (Eina_Bool *)data;
+ *opened = EINA_TRUE;
+ eina_file_close(*file);
+ ecore_main_loop_quit();
+}
+
+static void
+_stat_done_cb(void *data, const Eina_Stat **stat)
+{
+ Eina_Bool *is_dir = (Eina_Bool *)data;
+ unsigned int rights;
+ fail_if(eio_file_is_dir(*stat) != *is_dir);
+ fail_if(eio_file_is_lnk(*stat));
+ rights = (*stat)->mode & (S_IRWXU | S_IRWXG | S_IRWXO);
+ fail_if(rights != default_rights);
+ ecore_main_loop_quit();
+}
+
+typedef void (*Eio_Job_Test_Stat_Ls_Func)(Eo *job, const char *path, Eina_Promise **promise);
+
+static void
+_do_ls_test(Eio_Job_Test_Stat_Ls_Func ls_func,
+ const Eo_Event_Description *event,
+ Eo_Event_Cb filter_cb,
+ Eina_Promise_Progress_Cb progress_cb,
+ int expected_test_count,
+ const char* test_dirname)
+{
+ int main_files = 0;
+
+ Eio_Job *job = eo_add(EIO_JOB_CLASS, NULL);
+ Eina_Promise *promise = NULL;
+
+ eo_event_callback_add(job, event, filter_cb, NULL);
+ ls_func(job, test_dirname, &promise);
+ test_count = expected_test_count;
+ eina_promise_progress_cb_add(promise, progress_cb, &main_files, NULL);
+ eina_promise_then(promise,
+ (Eina_Promise_Cb)&_done_cb,
+ (Eina_Promise_Error_Cb)&_error_cb,
+ &main_files);
+
+ ecore_main_loop_begin();
+
+ fail_if(main_files != DONE_CALLED);
+
+ eo_unref(job);
+}
+
+static void
+_do_direct_ls_test(Eio_Job_Test_Stat_Ls_Func ls_func,
+ int expected_test_count,
+ const char *test_dirname)
+{
+ _do_ls_test(ls_func,
+ EIO_JOB_EVENT_FILTER_DIRECT,
+ (Eo_Event_Cb)&_filter_direct_cb,
+ (Eina_Promise_Progress_Cb)&_main_direct_cb,
+ expected_test_count,
+ test_dirname);
+}
+
+START_TEST(eio_job_test_file_direct_stat)
+{
+ Eina_Bool is_dir;
+ int ret;
+
+ ret = ecore_init();
+ fail_if(ret < 1);
+ ret = eio_init();
+ fail_if(ret < 1);
+ ret = eina_init();
+ fail_if(ret < 1);
+ ret = ecore_file_init();
+ fail_if(ret < 1);
+
+ Eina_Tmpstr *test_dirname = get_eio_test_file_tmp_dir();
+ Eina_Tmpstr *nested_dirname = create_test_dirs(test_dirname);
+ Eina_Tmpstr *nested_filename = get_full_path(test_dirname, files[3]);
+
+ Eio_Job *job = eo_add(EIO_JOB_CLASS, NULL);
+ Eina_Promise *promise = NULL;
+ // Start testing
+ is_dir = EINA_TRUE;
+
+ eio_job_file_direct_stat(job, nested_dirname, &promise);
+ eina_promise_then(promise, (Eina_Promise_Cb)&_stat_done_cb, (Eina_Promise_Error_Cb)&_error_cb, &is_dir);
+ ecore_main_loop_begin();
+
+ is_dir = EINA_FALSE;
+ eio_job_file_direct_stat(job, nested_filename, &promise);
+ eina_promise_then(promise, (Eina_Promise_Cb)&_stat_done_cb, (Eina_Promise_Error_Cb)&_error_cb, &is_dir);
+ ecore_main_loop_begin();
+ eo_unref(job);
+
+ // Cleanup
+ fail_if(!ecore_file_recursive_rm(test_dirname));
+
+ eina_tmpstr_del(nested_dirname);
+ eina_tmpstr_del(test_dirname);
+ eina_tmpstr_del(nested_filename);
+ ecore_file_shutdown();
+ eina_shutdown();
+ eio_shutdown();
+ ecore_shutdown();
+}
+END_TEST
+
+START_TEST(eio_job_test_ls_funcs)
+{
+ int ret;
+
+ ret = ecore_init();
+ fail_if(ret < 1);
+ ret = eio_init();
+ fail_if(ret < 1);
+ ret = eina_init();
+ fail_if(ret < 1);
+ ret = ecore_file_init();
+ fail_if(ret < 1);
+
+ Eina_Tmpstr *test_dirname = get_eio_test_file_tmp_dir();
+ Eina_Tmpstr *nested_dirname = create_test_dirs(test_dirname);
+ Eina_Tmpstr *nested_filename = get_full_path(test_dirname, files[3]);
+
+ // Start testing
+
+ _do_ls_test(&eio_job_file_ls,
+ EIO_JOB_EVENT_FILTER_NAME,
+ (Eo_Event_Cb)&_filter_cb,
+ (Eina_Promise_Progress_Cb)&_main_cb,
+ 5,
+ test_dirname);
+
+ _do_direct_ls_test(&eio_job_file_stat_ls, 5, test_dirname);
+
+ _do_direct_ls_test(&eio_job_file_direct_ls, 5, test_dirname);
+
+ _do_direct_ls_test(&eio_job_dir_stat_ls, 8, test_dirname);
+
+ _do_direct_ls_test(&eio_job_dir_direct_ls, 8, test_dirname);
+
+ // Cleanup
+ fail_if(!ecore_file_recursive_rm(test_dirname));
+
+ eina_tmpstr_del(nested_dirname);
+ eina_tmpstr_del(test_dirname);
+ eina_tmpstr_del(nested_filename);
+ ecore_file_shutdown();
+ eina_shutdown();
+ eio_shutdown();
+ ecore_shutdown();
+}
+END_TEST
+
+START_TEST(eio_job_test_open)
+{
+ Eina_Bool opened_file;
+ int ret;
+
+ ret = ecore_init();
+ fail_if(ret < 1);
+ ret = eio_init();
+ fail_if(ret < 1);
+ ret = eina_init();
+ fail_if(ret < 1);
+ ret = ecore_file_init();
+ fail_if(ret < 1);
+
+ Eina_Tmpstr *test_dirname = get_eio_test_file_tmp_dir();
+ Eina_Tmpstr *nested_dirname = create_test_dirs(test_dirname);
+ Eina_Tmpstr *nested_filename = get_full_path(test_dirname, files[3]);
+
+ opened_file = EINA_FALSE;
+ Eio_Job *job = eo_add(EIO_JOB_CLASS, NULL);
+ Eina_Promise *promise = NULL;
+
+ eio_job_file_open(job, nested_filename, EINA_FALSE, &promise);
+ eina_promise_then(promise, (Eina_Promise_Cb)&_open_done_cb, (Eina_Promise_Error_Cb)&_error_cb, &opened_file);
+ ecore_main_loop_begin();
+ eo_unref(job);
+ fail_if(!opened_file);
+
+ // Cleanup
+ fail_if(!ecore_file_recursive_rm(test_dirname));
+
+ eina_tmpstr_del(nested_dirname);
+ eina_tmpstr_del(test_dirname);
+ eina_tmpstr_del(nested_filename);
+ ecore_file_shutdown();
+ eina_shutdown();
+ eio_shutdown();
+ ecore_shutdown();
+}
+END_TEST
+
+void
+eio_test_job(TCase *tc)
+{
+ tcase_add_test(tc, eio_job_test_ls_funcs);
+ tcase_add_test(tc, eio_job_test_file_direct_stat);
+ tcase_add_test(tc, eio_job_test_open);
+}
+; \ No newline at end of file
diff --git a/src/tests/eio/eio_test_job_xattr.c b/src/tests/eio/eio_test_job_xattr.c
new file mode 100644
index 0000000000..0cf5aca0fe
--- /dev/null
+++ b/src/tests/eio/eio_test_job_xattr.c
@@ -0,0 +1,204 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+
+#include <Ecore.h>
+#include <Ecore_File.h>
+#include <Eio.h>
+
+#include "eio_suite.h"
+#include "eio_test_common.h"
+
+
+#ifdef XATTR_TEST_DIR
+
+static const char *attribute[] =
+ {
+ "user.comment1",
+ "user.comment2",
+ "user.comment3"
+ };
+static const char *attr_data[] =
+ {
+ "This is a test file",
+ "This line is a comment",
+ "This file has extra attributes"
+ };
+
+struct eina_iterator
+{
+ Eina_Iterator* success_iterator;
+ Eina_Iterator* failure_iterator;
+};
+
+int total_attributes = sizeof(attribute)/sizeof(attribute[0]);
+
+static Eina_Bool
+_filter_cb(void *data EINA_UNUSED, const Eo_Event *event)
+{
+ Eio_Filter_Name_Data *event_info = event->info;
+
+ return event_info->filter = EINA_TRUE;
+}
+
+static void
+_main_cb(void *data, const char *attr)
+{
+ int *num_of_attr = (int *)data;
+ unsigned int i;
+
+ for (i = 0; i < sizeof (attribute) / sizeof (attribute[0]); ++i)
+ if (strcmp(attr, attribute[i]) == 0)
+ {
+ (*num_of_attr)++;
+ break;
+ }
+
+}
+
+static void
+_done_cb(void *data, void *value EINA_UNUSED)
+
+{
+ int *num_of_attr = (int *)data;
+
+ fail_if(*num_of_attr != total_attributes);
+
+ ecore_main_loop_quit();
+}
+
+static void
+_done_get_cb(void *data EINA_UNUSED, struct eina_iterator* it)
+{
+ int i = 0;
+ Eio_Xattr_Data *get_data;
+
+ while (eina_iterator_next(it->success_iterator, (void**)&get_data))
+ {
+ fail_if(!get_data);
+ fail_if(strcmp(get_data->data, attr_data[i]) != 0);
+ i++;
+ }
+
+ fail_if(i != total_attributes);
+
+ ecore_main_loop_quit();
+}
+
+static void
+_done_set_cb(void *data, struct eina_iterator* it)
+{
+ int *placeholder;
+ int *num_of_attr = data;
+ while(eina_iterator_next(it->success_iterator, (void**)&placeholder))
+ *num_of_attr += 1;
+
+ fail_if(*num_of_attr != total_attributes);
+
+ ecore_main_loop_quit();
+}
+
+static void
+_error_cb(void *data EINA_UNUSED, Eina_Error *error)
+
+{
+ fprintf(stderr, "Something has gone wrong:%s\n", strerror(*error));
+ abort();
+
+ ecore_main_loop_quit();
+}
+
+START_TEST(eio_test_job_xattr_set)
+{
+ char *filename = "eio-tmpfile";
+ Eina_Tmpstr *test_file_path;
+ int num_of_attr = 0, fd;
+ unsigned int i;
+ Eo *job;
+ Eina_Promise *list_promise = NULL;
+ Eina_Promise **attrib_promises = NULL;
+
+ ecore_init();
+ eina_init();
+ eio_init();
+
+ job = eo_add(EIO_JOB_CLASS, NULL);
+
+ test_file_path = get_full_path(XATTR_TEST_DIR, filename);
+ fd = open(test_file_path,
+ O_WRONLY | O_CREAT | O_TRUNC,
+ S_IRWXU | S_IRWXG | S_IRWXO);
+ fail_if(fd == 0);
+
+ attrib_promises = (Eina_Promise **)calloc(total_attributes + 1, sizeof(Eina_Promise*));
+ attrib_promises[total_attributes] = NULL;
+
+ for (i = 0; i < sizeof(attribute) / sizeof(attribute[0]); ++i)
+ {
+ eio_job_file_xattr_set(job, test_file_path, attribute[i],
+ attr_data[i], strlen(attr_data[i]),
+ EINA_XATTR_INSERT,
+ &attrib_promises[i]);
+
+ fail_if(num_of_attr != 0); // test asynchronous
+ }
+ eina_promise_then(eina_promise_all(eina_carray_iterator_new((void**)attrib_promises)),
+ (Eina_Promise_Cb)_done_set_cb, (Eina_Promise_Error_Cb)_error_cb, &num_of_attr);
+
+ ecore_main_loop_begin();
+
+ free(attrib_promises);
+
+ num_of_attr = 0;
+
+ attrib_promises = (Eina_Promise **)calloc(total_attributes + 1, sizeof(Eina_Promise*));
+ attrib_promises[total_attributes] = NULL;
+
+ for (i = 0; i < sizeof(attribute) / sizeof(attribute[0]); ++i)
+ {
+ eio_job_file_xattr_get(job, test_file_path, attribute[i], &attrib_promises[i]);
+ }
+
+ eina_promise_then(eina_promise_all(eina_carray_iterator_new((void**)attrib_promises)),
+ (Eina_Promise_Cb)_done_get_cb, (Eina_Promise_Error_Cb)_error_cb, &num_of_attr);
+
+ ecore_main_loop_begin();
+
+ num_of_attr = 0;
+
+ eo_event_callback_add(job, EIO_JOB_EVENT_XATTR, _filter_cb, NULL);
+ eio_job_file_xattr(job, test_file_path, &list_promise);
+ eina_promise_progress_cb_add(list_promise, (Eina_Promise_Progress_Cb)_main_cb, &num_of_attr, NULL);
+ eina_promise_then(list_promise, (Eina_Promise_Cb)_done_cb, (Eina_Promise_Error_Cb)_error_cb, &num_of_attr);
+
+ fail_if(num_of_attr != 0);
+
+ ecore_main_loop_begin();
+
+ free(attrib_promises);
+
+ eo_unref(job);
+ close(fd);
+ unlink(test_file_path);
+ eina_tmpstr_del(test_file_path);
+ eio_shutdown();
+ eina_shutdown();
+ ecore_shutdown();
+}
+END_TEST
+
+#endif
+
+void eio_test_job_xattr(TCase *tc)
+{
+#ifdef XATTR_TEST_DIR
+ tcase_add_test(tc, eio_test_job_xattr_set);
+#else
+ (void)tc;
+#endif
+}
diff --git a/src/tests/eio/eio_test_sentry.c b/src/tests/eio/eio_test_sentry.c
new file mode 100644
index 0000000000..4f3c6c768e
--- /dev/null
+++ b/src/tests/eio/eio_test_sentry.c
@@ -0,0 +1,755 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <Ecore.h>
+#include <Ecore_File.h>
+#include <Eio.h>
+
+#include "eio_suite.h"
+
+/////////////////timeout function
+
+#define TEST_TIMEOUT_SEC 10
+#define TEST_OPERATION_DELAY 0.5
+
+static Ecore_Timer *test_timeout_timer;
+
+static Eina_Bool _test_timeout_cb(void *data EINA_UNUSED)
+{
+ ck_abort_msg("test timeout");
+ ecore_main_loop_quit();
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static void _cancel_timeout()
+{
+ if (test_timeout_timer != NULL)
+ {
+ ecore_timer_del (test_timeout_timer);
+ test_timeout_timer = NULL;
+ }
+}
+
+static Eina_Bool _test_timeout_expected(void *data EINA_UNUSED)
+{
+ if (test_timeout_timer != NULL)
+ {
+ _cancel_timeout();
+ }
+ ecore_main_loop_quit();
+ return ECORE_CALLBACK_CANCEL;
+}
+
+///////////////// file and directory operations
+
+typedef struct {
+ const char *src;
+ const char *dst;
+} RenameOperation;
+
+static Eina_Bool _delete_directory(void *data)
+{
+ const char *dirname = (const char*)data;
+ if (ecore_file_is_dir(dirname))
+ {
+ ecore_file_recursive_rm(dirname);
+ }
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static Eina_Bool _create_directory(void *data)
+{
+ const char *dirname = (const char*)data;
+ ecore_file_mkpath(dirname);
+ return ECORE_CALLBACK_CANCEL;
+}
+
+
+static Eina_Bool _create_file(void *data)
+{
+ FILE *fd = fopen((const char*)data, "wb+");
+ ck_assert_ptr_ne(fd, NULL);
+ fprintf(fd, "test test");
+ fclose(fd);
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static Eina_Bool _delete_file(void *data)
+{
+ Eina_Bool file_removed = ecore_file_remove((const char*)data);
+ ck_assert(file_removed);
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static Eina_Bool _modify_file(void *data)
+{
+ FILE *fd = fopen((const char*)data, "ab");
+ ck_assert_ptr_ne(fd, NULL);
+ fprintf(fd, "appened");
+ fclose(fd);
+ return ECORE_CALLBACK_CANCEL;
+}
+
+static Eina_Bool _modify_attrib_file(void *data)
+{
+ int ret = chmod((const char*)data, 0666);
+ ck_assert_int_eq(ret, 0);
+ return ECORE_CALLBACK_CANCEL;
+}
+
+/////// helper functions
+
+static Eina_Bool _check_event_path(void *data, const Eo_Event *event)
+{
+ Eio_Sentry_Event *event_info = event->info;
+ ck_assert_str_eq((const char*)data, event_info->trigger);
+ return EINA_TRUE;
+}
+
+static Eina_Tmpstr *_common_init()
+{
+ Eina_Tmpstr *dirname;
+ fail_if(eio_init() != 1);
+ ecore_file_init();
+
+ //test timeout
+ test_timeout_timer = ecore_timer_add(TEST_TIMEOUT_SEC, _test_timeout_cb, NULL);
+
+ eina_file_mkdtemp("checkFileCreationXXXXXX", &dirname);
+ return dirname;
+}
+
+static void _common_shutdown(Eina_Tmpstr *dirname)
+{
+ _delete_directory((void*)dirname);
+ ecore_file_shutdown();
+ fail_if(eio_shutdown() != 0);
+ eina_tmpstr_del(dirname);
+}
+
+/////// tests monitoring a directory
+
+START_TEST(eio_test_sentry_add_and_remove)
+{
+ Eina_Tmpstr *dirname = _common_init();
+ Eina_Stringshare *filename;
+ Eo *sentry;
+
+ filename = eina_stringshare_printf("%s/eio_test_sentry_directory_file_created_notify", dirname);
+ _create_directory((void*)filename);
+
+ //sleep to avoid catching event generated by above manipulations
+ usleep(500000);
+
+ //monitor directory
+ sentry = eo_add(EIO_SENTRY_CLASS, NULL);
+ fail_if(!eio_sentry_add(sentry, filename));
+
+ usleep(500000);
+
+ eio_sentry_del(sentry, filename);
+
+ eo_unref(sentry);
+
+ _common_shutdown(dirname);
+}
+END_TEST
+
+START_TEST(eio_test_sentry_add_remove_add)
+{
+ Eina_Tmpstr *dirname = _common_init();
+ Eina_Stringshare *filename;
+ Eo* sentry;
+
+ filename = eina_stringshare_printf("%s/eio_test_sentry_add_remove_add", dirname);
+ _create_directory((void*)filename);
+
+ //sleep to avoid catching event generated by above manipulations
+ usleep(500000);
+
+ //monitor directory
+ sentry = eo_add(EIO_SENTRY_CLASS, NULL);
+ fail_if(!eio_sentry_add(sentry, filename));
+ eio_sentry_del(sentry, filename);
+
+ usleep(500000);
+
+ fail_if(!eio_sentry_add(sentry, filename));
+ eio_sentry_del(sentry, filename);
+
+ eo_unref(sentry);
+
+ _common_shutdown(dirname);
+}
+END_TEST
+
+START_TEST(eio_test_sentry_add_add_remove_remove)
+{
+ Eina_Tmpstr *dirname = _common_init();
+ Eina_Stringshare *filename1;
+ Eina_Stringshare *filename2;
+ Eo *sentry;
+
+ filename1 = eina_stringshare_printf("%s/eio_test_sentry_add_add_remove_remove", dirname);
+ filename2 = eina_stringshare_printf("%s/eio_test_sentry_add_add_remove_remove", dirname);
+ _create_directory((void*)filename1);
+ _create_directory((void*)filename2);
+
+ //sleep to avoid catching event generated by above manipulations
+ usleep(500000);
+
+ sentry = eo_add(EIO_SENTRY_CLASS, NULL);
+
+ //monitor directory
+ fail_if(!eio_sentry_add(sentry, filename1));
+ fail_if(!eio_sentry_add(sentry, filename2));
+ usleep(500000);
+ eio_sentry_del(sentry, filename1);
+ eio_sentry_del(sentry, filename2);
+
+ eo_unref(sentry);
+
+ _common_shutdown(dirname);
+}
+END_TEST
+
+static void _target_notified_cb(void *data, const Eo_Event *event)
+{
+ if (_check_event_path(data, event))
+ {
+ _cancel_timeout();
+ ecore_main_loop_quit();
+ }
+}
+
+
+START_TEST(eio_test_sentry_directory_file_created_notify)
+{
+ Eina_Tmpstr *dirname = _common_init();
+ Eina_Stringshare *filename;
+ Eo* sentry;
+
+ filename = eina_stringshare_printf("%s/eio_test_sentry_directory_file_created_notify", dirname);
+ sentry = eo_add(EIO_SENTRY_CLASS, NULL);
+
+ //sleep to avoid catching event generated by above manipulations
+ usleep(500000);
+
+ //monitor directory
+ fail_if(!eio_sentry_add(sentry, dirname));
+ eo_event_callback_add(sentry, EIO_SENTRY_EVENT_FILE_CREATED, (Eo_Event_Cb)_target_notified_cb, filename);
+
+ ecore_timer_add(TEST_OPERATION_DELAY, _create_file, filename);
+
+ ecore_main_loop_begin();
+
+ eo_unref(sentry);
+
+ _common_shutdown(dirname);
+}
+END_TEST
+
+START_TEST(eio_test_sentry_directory_file_deleted_notify)
+{
+ Eina_Tmpstr *dirname = _common_init();
+ Eina_Stringshare *filename;
+ Eo *sentry;
+
+ filename = eina_stringshare_printf("%s/eio_test_sentry_directory_file_deleted_notify", dirname);
+ _create_file((void*)filename);
+ sentry = eo_add(EIO_SENTRY_CLASS, NULL);
+
+ //sleep to avoid catching event generated by above manipulations
+ usleep(500000);
+
+ //monitor directory
+ fail_if(!eio_sentry_add(sentry, dirname));
+ eo_event_callback_add(sentry, EIO_SENTRY_EVENT_FILE_DELETED, (Eo_Event_Cb)_target_notified_cb, filename);
+
+ ecore_timer_add(TEST_OPERATION_DELAY, _delete_file, filename);
+
+ ecore_main_loop_begin();
+
+ eo_unref(sentry);
+
+ _common_shutdown(dirname);
+}
+END_TEST
+
+START_TEST(eio_test_sentry_directory_file_modified_notify)
+{
+ Eina_Tmpstr *dirname = _common_init();
+ Eina_Stringshare *filename;
+ Eo *sentry;
+
+ filename = eina_stringshare_printf("%s/eio_test_sentry_directory_file_modified_notify", dirname);
+ _create_file((void*)filename);
+ sentry = eo_add(EIO_SENTRY_CLASS, NULL);
+
+ //sleep to avoid catching event generated by above manipulations
+ usleep(500000);
+
+ //monitor directory
+ fail_if(!eio_sentry_add(sentry, dirname));
+ eo_event_callback_add(sentry, EIO_SENTRY_EVENT_FILE_MODIFIED, (Eo_Event_Cb)_target_notified_cb, filename);
+
+ ecore_timer_add(TEST_OPERATION_DELAY, _modify_file, filename);
+
+ ecore_main_loop_begin();
+
+ eo_unref(sentry);
+
+ //cleanup
+ _common_shutdown(dirname);
+}
+END_TEST
+
+START_TEST(eio_test_sentry_directory_file_closed_notify)
+{
+ Eina_Tmpstr *dirname = _common_init();
+ Eina_Stringshare *filename;
+ Eo *sentry;
+
+ filename = eina_stringshare_printf("%s/eio_test_sentry_directory_file_closed_notify", dirname);
+ _create_file((void*)filename);
+ sentry = eo_add(EIO_SENTRY_CLASS, NULL);
+
+ //sleep to avoid catching event generated by above manipulations
+ usleep(500000);
+
+ //monitor directory
+ fail_if(!eio_sentry_add(sentry, dirname));
+ eo_event_callback_add(sentry, EIO_SENTRY_EVENT_FILE_CLOSED, (Eo_Event_Cb)_target_notified_cb, filename);
+ ecore_timer_add(TEST_OPERATION_DELAY, _modify_file, filename);
+
+ ecore_main_loop_begin();
+
+ eo_unref(sentry);
+
+ _common_shutdown(dirname);
+}
+END_TEST
+
+START_TEST(eio_test_sentry_directory_directory_created_notify)
+{
+ Eina_Tmpstr *dirname = _common_init();
+ Eina_Stringshare *filename;
+ Eo *sentry;
+
+ filename = eina_stringshare_printf("%s/eio_test_sentry_directory_directory_created_notify", dirname);
+ sentry = eo_add(EIO_SENTRY_CLASS, NULL);
+
+ //sleep to avoid catching event generated by above manipulations
+ usleep(500000);
+
+ //monitor directory
+ fail_if(!eio_sentry_add(sentry, dirname));
+ eo_event_callback_add(sentry, EIO_SENTRY_EVENT_DIRECTORY_CREATED, (Eo_Event_Cb)_target_notified_cb, filename);
+
+ ecore_timer_add(TEST_OPERATION_DELAY, _create_directory, filename);
+
+ ecore_main_loop_begin();
+
+ eo_unref(sentry);
+
+ _common_shutdown(dirname);
+}
+END_TEST
+
+START_TEST(eio_test_sentry_directory_directory_deleted_notify)
+{
+ Eina_Tmpstr *dirname = _common_init();
+ Eina_Stringshare *filename;
+ Eo *sentry;
+
+ filename = eina_stringshare_printf("%s/eio_test_sentry_directory_directory_deleted_notify", dirname);
+ _create_directory((void*)filename);
+ sentry = eo_add(EIO_SENTRY_CLASS, NULL);
+
+ //sleep to avoid catching event generated by above manipulations
+ usleep(500000);
+
+ //monitor directory
+ fail_if(!eio_sentry_add(sentry, dirname));
+ eo_event_callback_add(sentry, EIO_SENTRY_EVENT_DIRECTORY_DELETED, (Eo_Event_Cb)_target_notified_cb, filename);
+
+ ecore_timer_add(TEST_OPERATION_DELAY, _delete_directory, filename);
+
+ ecore_main_loop_begin();
+
+ eo_unref(sentry);
+
+ _common_shutdown(dirname);
+}
+END_TEST
+
+START_TEST(eio_test_sentry_directory_directory_modified_notify)
+{
+ Eina_Tmpstr *dirname = _common_init();
+ Eina_Stringshare *filename;
+ Eo *sentry;
+
+ filename = eina_stringshare_printf("%s/eio_test_sentry_directory_directory_modified_notify", dirname);
+ _create_directory((void*)filename);
+ sentry = eo_add(EIO_SENTRY_CLASS, NULL);
+
+ //sleep to avoid catching event generated by above manipulations
+ usleep(500000);
+
+ //monitor directory
+ fail_if(!eio_sentry_add(sentry, dirname));
+ eo_event_callback_add(sentry, EIO_SENTRY_EVENT_DIRECTORY_MODIFIED, (Eo_Event_Cb)_target_notified_cb, filename);
+
+ ecore_timer_add(TEST_OPERATION_DELAY, _modify_attrib_file, filename);
+
+ ecore_main_loop_begin();
+
+ eo_unref(sentry);
+
+ _common_shutdown(dirname);
+}
+END_TEST
+
+START_TEST(eio_test_sentry_directory_directory_self_deleted_notify)
+{
+ Eina_Tmpstr *dirname = _common_init();
+ Eo *sentry = eo_add(EIO_SENTRY_CLASS, NULL);
+
+ //sleep to avoid catching event generated by above manipulations
+ usleep(500000);
+
+ //monitor directory
+ fail_if(!eio_sentry_add(sentry, dirname));
+ eo_event_callback_add(sentry, EIO_SENTRY_EVENT_SELF_DELETED, (Eo_Event_Cb)_target_notified_cb, dirname);
+
+ ecore_timer_add(TEST_OPERATION_DELAY, _delete_directory, dirname);
+
+ ecore_main_loop_begin();
+
+ eo_unref(sentry);
+
+ _common_shutdown(dirname);
+}
+END_TEST
+
+// //////// test monitoring a single file
+
+START_TEST(eio_test_sentry_file_file_modified_notify)
+{
+ Eina_Tmpstr *dirname = _common_init();
+ Eina_Stringshare *filename;
+ Eo *sentry;
+
+ filename = eina_stringshare_printf("%s/filecreated", dirname);
+ _create_file((void*)filename);
+ sentry = eo_add(EIO_SENTRY_CLASS, NULL);
+
+ //sleep to avoid catching event generated by above manipulations
+ usleep(500000);
+
+ //monitor file
+ fail_if(!eio_sentry_add(sentry, filename));
+ eo_event_callback_add(sentry, EIO_SENTRY_EVENT_FILE_MODIFIED, (Eo_Event_Cb)_target_notified_cb, filename);
+
+ ecore_timer_add(TEST_OPERATION_DELAY, _modify_file, filename);
+
+ ecore_main_loop_begin();
+
+ eo_unref(sentry);
+
+ //cleanup
+ _common_shutdown(dirname);
+}
+END_TEST
+
+START_TEST(eio_test_sentry_file_file_attrib_modified_notify)
+{
+ Eina_Tmpstr *dirname = _common_init();
+ Eina_Stringshare *filename;
+ Eo *sentry;
+
+ filename = eina_stringshare_printf("%s/eio_test_sentry_file_file_attrib_modified_notify", dirname);
+ _create_file((void*)filename);
+ sentry = eo_add(EIO_SENTRY_CLASS, NULL);
+
+ //sleep to avoid catching event generated by above manipulations
+ usleep(500000);
+
+ //monitor file
+ fail_if(!eio_sentry_add(sentry, filename));
+ eo_event_callback_add(sentry, EIO_SENTRY_EVENT_FILE_MODIFIED, (Eo_Event_Cb)_target_notified_cb, filename);
+
+ ecore_timer_add(TEST_OPERATION_DELAY, _modify_attrib_file, filename);
+
+ ecore_main_loop_begin();
+
+ eo_unref(sentry);
+
+ _common_shutdown(dirname);
+}
+END_TEST
+
+
+START_TEST(eio_test_sentry_file_file_closed_notify)
+{
+ Eina_Tmpstr *dirname = _common_init();
+ Eina_Stringshare *filename;
+ Eo* sentry;
+
+ filename = eina_stringshare_printf("%s/eio_test_sentry_file_file_closed_notify", dirname);
+ _create_file((void*)filename);
+ sentry = eo_add(EIO_SENTRY_CLASS, NULL);
+
+ //sleep to avoid catching event generated by above manipulations
+ usleep(500000);
+
+ //monitor file
+ fail_if(!eio_sentry_add(sentry, dirname));
+ eo_event_callback_add(sentry, EIO_SENTRY_EVENT_FILE_CLOSED, (Eo_Event_Cb)_target_notified_cb, filename);
+ ecore_timer_add(TEST_OPERATION_DELAY, _modify_file, filename);
+
+ ecore_main_loop_begin();
+
+ eo_unref(sentry);
+
+ _common_shutdown(dirname);
+}
+END_TEST
+
+START_TEST(eio_test_sentry_file_file_self_deleted_notify)
+{
+ Eina_Tmpstr *dirname = _common_init();
+ Eina_Stringshare *filename;
+ Eo* sentry;
+
+ filename = eina_stringshare_printf("%s/eio_test_sentry_file_file_self_deleted_notify", dirname);
+ _create_file((void*)filename);
+ sentry = eo_add(EIO_SENTRY_CLASS, NULL);
+
+ //sleep to avoid catching event generated by above manipulations
+ usleep(500000);
+
+ //monitor file
+ fail_if(!eio_sentry_add(sentry, filename));
+ eo_event_callback_add(sentry, EIO_SENTRY_EVENT_SELF_DELETED, (Eo_Event_Cb)_target_notified_cb, filename);
+
+ ecore_timer_add(TEST_OPERATION_DELAY, _delete_file, filename);
+
+ ecore_main_loop_begin();
+
+ eo_unref(sentry);
+
+ _common_shutdown(dirname);
+}
+END_TEST
+
+START_TEST(eio_test_sentry_two_monitors_one_event)
+{
+ Eina_Tmpstr *dirname = _common_init();
+ Eina_Tmpstr *dirname2;
+ Eo *sentry;
+
+ Eina_Stringshare *filename;
+
+ eina_file_mkdtemp("checkFileCreationXXXXXX", &dirname2);
+ filename = eina_stringshare_printf("%s/eio_test_sentry_two_monitors_one_event", dirname);
+ sentry = eo_add(EIO_SENTRY_CLASS, NULL);
+
+ //sleep to avoid catching event generated by above manipulations
+ usleep(500000);
+
+ //monitor directory
+ fail_if(!eio_sentry_add(sentry, dirname));
+ fail_if(!eio_sentry_add(sentry, dirname2));
+ eo_event_callback_add(sentry, EIO_SENTRY_EVENT_FILE_CREATED, (Eo_Event_Cb)_target_notified_cb, filename);
+
+ ecore_timer_add(TEST_OPERATION_DELAY, _create_file, filename);
+
+ ecore_main_loop_begin();
+
+ eo_unref(sentry);
+
+ _delete_directory((void*)dirname2);
+ _common_shutdown(dirname);
+}
+END_TEST
+
+
+START_TEST(eio_test_sentry_two_monitors_one_removed_one_event)
+{
+ Eina_Tmpstr *dirname = _common_init();
+ Eina_Tmpstr *dirname2;
+ Eo *sentry;
+
+ Eina_Stringshare *filename;
+
+ eina_file_mkdtemp("checkFileCreationXXXXXX", &dirname2);
+ filename = eina_stringshare_printf("%s/eio_test_sentry_two_monitors_one_removed", dirname);
+ sentry = eo_add(EIO_SENTRY_CLASS, NULL);
+
+ //sleep to avoid catching event generated by above manipulations
+ usleep(500000);
+
+ //monitor directory
+ fail_if(!eio_sentry_add(sentry, dirname2));
+ fail_if(!eio_sentry_add(sentry, dirname));
+ eio_sentry_del(sentry, dirname2);
+ eo_event_callback_add(sentry, EIO_SENTRY_EVENT_FILE_CREATED, (Eo_Event_Cb)_target_notified_cb, filename);
+
+ ecore_timer_add(TEST_OPERATION_DELAY, _create_file, filename);
+
+ ecore_main_loop_begin();
+
+ eo_unref(sentry);
+
+ _delete_directory((void*)dirname2);
+ _common_shutdown(dirname);
+}
+END_TEST
+
+static void _unexpected_event_cb(void *data EINA_UNUSED, const Eo_Event *event EINA_UNUSED)
+{
+ ck_abort_msg("unexpected event");
+}
+
+START_TEST(eio_test_sentry_two_monitors_one_removed_no_event)
+{
+ Eina_Tmpstr *dirname = _common_init();
+ Eina_Tmpstr *dirname2;
+ Eo *sentry;
+
+ Eina_Stringshare *filename;
+
+ eina_file_mkdtemp("checkFileCreationXXXXXX", &dirname2);
+ filename = eina_stringshare_printf("%s/eio_test_sentry_two_monitors_one_removed", dirname);
+ sentry = eo_add(EIO_SENTRY_CLASS, NULL);
+
+ //sleep to avoid catching event generated by above manipulations
+ usleep(500000);
+
+ //monitor directory
+ fail_if(!eio_sentry_add(sentry, dirname));
+ fail_if(!eio_sentry_add(sentry, dirname2));
+ eio_sentry_del(sentry, dirname);
+ eo_event_callback_add(sentry, EIO_SENTRY_EVENT_FILE_CREATED, (Eo_Event_Cb)_unexpected_event_cb, filename);
+
+ ecore_timer_add(TEST_OPERATION_DELAY, _create_file, filename);
+ ecore_timer_add(TEST_TIMEOUT_SEC - 1, _test_timeout_expected, NULL);
+
+ ecore_main_loop_begin();
+
+ eo_unref(sentry);
+
+ _delete_directory((void*)dirname2);
+ _common_shutdown(dirname);
+}
+END_TEST
+
+START_TEST(eio_test_sentry_two_files_in_same_directory)
+{
+ Eina_Tmpstr *dirname = _common_init();
+ Eina_Stringshare *filename;
+ Eina_Stringshare *filename2;
+ Eo *sentry;
+
+ filename = eina_stringshare_printf("%s/eio_test_sentry_two_files_in_same_directory_1", dirname);
+ filename2 = eina_stringshare_printf("%s/eio_test_sentry_two_files_in_same_directory_2", dirname);
+ _create_file((void*)filename);
+ _create_file((void*)filename2);
+ sentry = eo_add(EIO_SENTRY_CLASS, NULL);
+
+ //sleep to avoid catching event generated by above manipulations
+ usleep(500000);
+
+ //monitor file
+ fail_if(!eio_sentry_add(sentry,filename));
+ fail_if(!eio_sentry_add(sentry,filename2));
+ eo_event_callback_add(sentry, EIO_SENTRY_EVENT_FILE_MODIFIED, (Eo_Event_Cb)_target_notified_cb, filename);
+
+ ecore_timer_add(TEST_OPERATION_DELAY, _modify_file, filename);
+
+ ecore_main_loop_begin();
+
+ eo_unref(sentry);
+
+ //cleanup
+ _common_shutdown(dirname);
+}
+END_TEST
+
+
+START_TEST(eio_test_sentry_two_files_in_same_directory_one_removed)
+{
+ Eina_Tmpstr *dirname = _common_init();
+ Eina_Stringshare *filename;
+ Eina_Stringshare *filename2;
+ Eo *sentry;
+
+ filename = eina_stringshare_printf("%s/eio_test_sentry_two_files_in_same_directory_one_removed_1", dirname);
+ filename2 = eina_stringshare_printf("%s/eio_test_sentry_two_files_in_same_directory_one_removed_2", dirname);
+ _create_file((void*)filename);
+ _create_file((void*)filename2);
+ sentry = eo_add(EIO_SENTRY_CLASS, NULL);
+
+ //sleep to avoid catching event generated by above manipulations
+ usleep(500000);
+
+ //monitor file
+ fail_if(!eio_sentry_add(sentry,filename));
+ fail_if(!eio_sentry_add(sentry,filename2));
+ eio_sentry_del(sentry, filename);
+
+ eo_event_callback_add(sentry, EIO_SENTRY_EVENT_FILE_MODIFIED, (Eo_Event_Cb)_unexpected_event_cb, filename);
+
+ ecore_timer_add(TEST_OPERATION_DELAY, _modify_file, filename);
+ ecore_timer_add(TEST_TIMEOUT_SEC - 1, _test_timeout_expected, NULL);
+
+ ecore_main_loop_begin();
+
+ eo_unref(sentry);
+
+ //cleanup
+ _common_shutdown(dirname);
+}
+END_TEST
+
+
+void eio_test_sentry(TCase *tc)
+{
+ tcase_add_test(tc, eio_test_sentry_add_and_remove);
+ tcase_add_test(tc, eio_test_sentry_add_remove_add);
+ tcase_add_test(tc, eio_test_sentry_add_add_remove_remove);
+
+ tcase_add_test(tc, eio_test_sentry_directory_file_created_notify);
+ tcase_add_test(tc, eio_test_sentry_directory_file_deleted_notify);
+ tcase_add_test(tc, eio_test_sentry_directory_file_modified_notify);
+#if !defined(_WIN32) && !defined(__MACH__)
+ tcase_add_test(tc, eio_test_sentry_directory_file_closed_notify);
+#endif
+ tcase_add_test(tc, eio_test_sentry_directory_directory_created_notify);
+ tcase_add_test(tc, eio_test_sentry_directory_directory_deleted_notify);
+ tcase_add_test(tc, eio_test_sentry_directory_directory_modified_notify);
+#ifndef __MACH__
+ tcase_add_test(tc, eio_test_sentry_directory_directory_self_deleted_notify);
+#endif
+
+ tcase_add_test(tc, eio_test_sentry_file_file_modified_notify);
+ tcase_add_test(tc, eio_test_sentry_file_file_attrib_modified_notify);
+#if !defined(_WIN32) && !defined(__MACH__)
+ tcase_add_test(tc, eio_test_sentry_file_file_closed_notify);
+#endif
+#ifndef __MACH__
+ tcase_add_test(tc, eio_test_sentry_file_file_self_deleted_notify);
+#endif
+
+ tcase_add_test(tc, eio_test_sentry_two_monitors_one_event);
+ tcase_add_test(tc, eio_test_sentry_two_monitors_one_removed_one_event);
+ tcase_add_test(tc, eio_test_sentry_two_monitors_one_removed_no_event);
+ tcase_add_test(tc, eio_test_sentry_two_files_in_same_directory);
+ tcase_add_test(tc, eio_test_sentry_two_files_in_same_directory_one_removed);
+}
diff --git a/src/tests/eio/eio_test_xattr.c b/src/tests/eio/eio_test_xattr.c
index 1a50c125e5..b4a843ea10 100644
--- a/src/tests/eio/eio_test_xattr.c
+++ b/src/tests/eio/eio_test_xattr.c
@@ -12,6 +12,7 @@
#include <Eio.h>
#include "eio_suite.h"
+#include "eio_test_common.h"
#ifdef XATTR_TEST_DIR
@@ -23,27 +24,19 @@ static int int_data = 1234;
static char *double_attr = "user.size";
static double double_data = 123.456;
-const char *attribute[] =
+static const char *attribute[] =
{
"user.comment1",
"user.comment2",
"user.comment3"
};
-const char *attr_data[] =
+static const char *attr_data[] =
{
"This is a test file",
"This line is a comment",
"This file has extra attributes"
};
-Eina_Tmpstr*
-get_file_path(const char* tmpdirname, const char* filename)
-{
- char file_path[PATH_MAX] = "";
- eina_str_join(file_path, sizeof(file_path), '/', tmpdirname, filename);
- return eina_tmpstr_add(file_path);
-}
-
static Eina_Bool
_filter_cb(void *data EINA_UNUSED, Eio_File *handler EINA_UNUSED, const char *attr EINA_UNUSED)
{
@@ -149,7 +142,7 @@ START_TEST(eio_test_xattr_set)
eina_init();
eio_init();
- test_file_path = get_file_path(XATTR_TEST_DIR, filename);
+ test_file_path = get_full_path(XATTR_TEST_DIR, filename);
fd = open(test_file_path,
O_WRONLY | O_CREAT | O_TRUNC,
S_IRWXU | S_IRWXG | S_IRWXO);
@@ -207,7 +200,7 @@ START_TEST(eio_test_xattr_types_set)
eina_init();
eio_init();
- test_file_path = get_file_path(XATTR_TEST_DIR, filename);
+ test_file_path = get_full_path(XATTR_TEST_DIR, filename);
fd = open(test_file_path,
O_WRONLY | O_CREAT | O_TRUNC,
S_IRWXU | S_IRWXG | S_IRWXO);