summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);