diff options
author | Vincent Torri <vincent.torri@gmail.com> | 2012-12-04 17:40:58 +0000 |
---|---|---|
committer | Vincent Torri <vincent.torri@gmail.com> | 2012-12-04 17:40:58 +0000 |
commit | 81c86b19f6b432c5d6701bd025d5b2cf308fba4c (patch) | |
tree | 44f76300c96fddf3be01d97afb3025227350ee92 /src | |
parent | 633e29c5a50fa1a1087df88d8d9859c79a83e486 (diff) |
merge: eio + fix compilation on windows + minor fixes + po files
don't move eio to IN-EFL right now
SVN revision: 80180
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/Makefile_Ecore_Evas.am | 4 | ||||
-rw-r--r-- | src/Makefile_Eio.am | 50 | ||||
-rw-r--r-- | src/lib/eio/Eio.h | 1190 | ||||
-rw-r--r-- | src/lib/eio/eio_dir.c | 1001 | ||||
-rw-r--r-- | src/lib/eio/eio_eet.c | 640 | ||||
-rw-r--r-- | src/lib/eio/eio_file.c | 979 | ||||
-rw-r--r-- | src/lib/eio/eio_inline_helper.x | 105 | ||||
-rw-r--r-- | src/lib/eio/eio_main.c | 300 | ||||
-rw-r--r-- | src/lib/eio/eio_map.c | 316 | ||||
-rw-r--r-- | src/lib/eio/eio_monitor.c | 351 | ||||
-rw-r--r-- | src/lib/eio/eio_monitor_inotify.c | 273 | ||||
-rw-r--r-- | src/lib/eio/eio_monitor_poll.c | 354 | ||||
-rw-r--r-- | src/lib/eio/eio_monitor_win32.c | 425 | ||||
-rw-r--r-- | src/lib/eio/eio_private.h | 538 | ||||
-rw-r--r-- | src/lib/eio/eio_single.c | 594 | ||||
-rw-r--r-- | src/lib/eio/eio_xattr.c | 500 |
17 files changed, 7619 insertions, 2 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 2d2ae9e9c7..73ac3a9048 100644 --- a/src/Makefile.am +++ b/src/Makefile.am | |||
@@ -56,6 +56,7 @@ endif | |||
56 | include Makefile_Ecore_Imf.am | 56 | include Makefile_Ecore_Imf.am |
57 | include Makefile_Ecore_Evas.am | 57 | include Makefile_Ecore_Evas.am |
58 | include Makefile_Embryo.am | 58 | include Makefile_Embryo.am |
59 | include Makefile_Eio.am | ||
59 | 60 | ||
60 | .PHONY: benchmark examples | 61 | .PHONY: benchmark examples |
61 | 62 | ||
diff --git a/src/Makefile_Ecore_Evas.am b/src/Makefile_Ecore_Evas.am index f38c31ae84..40036b753d 100644 --- a/src/Makefile_Ecore_Evas.am +++ b/src/Makefile_Ecore_Evas.am | |||
@@ -107,10 +107,10 @@ if HAVE_WIN32 | |||
107 | lib_ecore_evas_libecore_evas_la_CPPFLAGS += \ | 107 | lib_ecore_evas_libecore_evas_la_CPPFLAGS += \ |
108 | -I$(top_srcdir)/src/lib/ecore_win32 \ | 108 | -I$(top_srcdir)/src/lib/ecore_win32 \ |
109 | -I$(top_srcdir)/src/modules/evas/engines/software_ddraw \ | 109 | -I$(top_srcdir)/src/modules/evas/engines/software_ddraw \ |
110 | -I$(top_srcdir)/src/modules/evas/engines/direct3d \ | 110 | -I$(top_srcdir)/src/modules/evas/engines/software_gdi \ |
111 | -I$(top_builddir)/src/lib/ecore_win32 \ | 111 | -I$(top_builddir)/src/lib/ecore_win32 \ |
112 | -I$(top_builddir)/src/modules/evas/engines/software_ddraw \ | 112 | -I$(top_builddir)/src/modules/evas/engines/software_ddraw \ |
113 | -I$(top_builddir)/src/modules/evas/engines/direct3d | 113 | -I$(top_builddir)/src/modules/evas/engines/software_gdi |
114 | endif | 114 | endif |
115 | 115 | ||
116 | if HAVE_WINCE | 116 | if HAVE_WINCE |
diff --git a/src/Makefile_Eio.am b/src/Makefile_Eio.am new file mode 100644 index 0000000000..93f4d25f93 --- /dev/null +++ b/src/Makefile_Eio.am | |||
@@ -0,0 +1,50 @@ | |||
1 | |||
2 | ### Library | ||
3 | |||
4 | lib_LTLIBRARIES += lib/eio/libeio.la | ||
5 | |||
6 | installed_eiomainheadersdir = $(includedir)/eio-@VMAJ@ | ||
7 | dist_installed_eiomainheaders_DATA = lib/eio/Eio.h lib/eio/eio_inline_helper.x | ||
8 | |||
9 | lib_eio_libeio_la_SOURCES = \ | ||
10 | lib/eio/eio_dir.c \ | ||
11 | lib/eio/eio_eet.c \ | ||
12 | lib/eio/eio_file.c \ | ||
13 | lib/eio/eio_main.c \ | ||
14 | lib/eio/eio_map.c \ | ||
15 | lib/eio/eio_monitor.c \ | ||
16 | lib/eio/eio_monitor_poll.c \ | ||
17 | lib/eio/eio_single.c \ | ||
18 | lib/eio/eio_xattr.c \ | ||
19 | lib/eio/eio_private.h | ||
20 | |||
21 | if EIO_HAVE_INOTIFY | ||
22 | lib_eio_libeio_la_SOURCES += lib/eio/eio_monitor_inotify.c | ||
23 | else | ||
24 | if EIO_HAVE_WINCHANGE | ||
25 | lib_eio_libeio_la_SOURCES += lib/eio/eio_monitor_win32.c | ||
26 | endif | ||
27 | endif | ||
28 | |||
29 | lib_eio_libeio_la_CPPFLAGS = \ | ||
30 | -I$(top_srcdir)/src/lib/eina \ | ||
31 | -I$(top_srcdir)/src/lib/eo \ | ||
32 | -I$(top_srcdir)/src/lib/eet \ | ||
33 | -I$(top_srcdir)/src/lib/ecore \ | ||
34 | -I$(top_srcdir)/src/lib/eio \ | ||
35 | -I$(top_builddir)/src/lib/eina \ | ||
36 | -I$(top_builddir)/src/lib/eo \ | ||
37 | -I$(top_builddir)/src/lib/eet \ | ||
38 | -I$(top_builddir)/src/lib/ecore \ | ||
39 | -I$(top_builddir)/src/lib/eio \ | ||
40 | -DEFL_EIO_BUILD \ | ||
41 | @EFL_CFLAGS@ | ||
42 | |||
43 | lib_eio_libeio_la_LIBADD = \ | ||
44 | lib/eina/libeina.la \ | ||
45 | lib/eo/libeo.la \ | ||
46 | lib/eet/libeet.la \ | ||
47 | lib/ecore/libecore.la \ | ||
48 | -lm | ||
49 | |||
50 | lib_eio_libeio_la_LDFLAGS = -no-undefined -version-info @version_info@ @release_info@ | ||
diff --git a/src/lib/eio/Eio.h b/src/lib/eio/Eio.h new file mode 100644 index 0000000000..cb791a0ebf --- /dev/null +++ b/src/lib/eio/Eio.h | |||
@@ -0,0 +1,1190 @@ | |||
1 | /* EIO - EFL data type library | ||
2 | * Copyright (C) 2010 Enlightenment Developers: | ||
3 | * Cedric Bail <cedric.bail@free.fr> | ||
4 | * Vincent "caro" Torri <vtorri at univ-evry dot fr> | ||
5 | * Stephen "okra" Houston <unixtitan@gmail.com> | ||
6 | * | ||
7 | * This library is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This library is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library; | ||
19 | * if not, see <http://www.gnu.org/licenses/>. | ||
20 | */ | ||
21 | |||
22 | #ifndef EIO_H__ | ||
23 | # define EIO_H__ | ||
24 | |||
25 | #include <sys/types.h> | ||
26 | #include <sys/stat.h> | ||
27 | #include <unistd.h> | ||
28 | |||
29 | #include <Eina.h> | ||
30 | #include <Eet.h> | ||
31 | |||
32 | #ifdef EAPI | ||
33 | # undef EAPI | ||
34 | #endif | ||
35 | |||
36 | #ifdef _WIN32 | ||
37 | # ifdef EFL_EIO_BUILD | ||
38 | # ifdef DLL_EXPORT | ||
39 | # define EAPI __declspec(dllexport) | ||
40 | # else | ||
41 | # define EAPI | ||
42 | # endif /* ! DLL_EXPORT */ | ||
43 | # else | ||
44 | # define EAPI __declspec(dllimport) | ||
45 | # endif /* ! EFL_EIO_BUILD */ | ||
46 | #else | ||
47 | # ifdef __GNUC__ | ||
48 | # if __GNUC__ >= 4 | ||
49 | # define EAPI __attribute__ ((visibility("default"))) | ||
50 | # else | ||
51 | # define EAPI | ||
52 | # endif | ||
53 | # else | ||
54 | # define EAPI | ||
55 | # endif | ||
56 | #endif /* ! _WIN32 */ | ||
57 | |||
58 | |||
59 | #ifdef __cplusplus | ||
60 | extern "C" { | ||
61 | #endif | ||
62 | |||
63 | #define EIO_VERSION_MAJOR 1 | ||
64 | #define EIO_VERSION_MINOR 8 | ||
65 | |||
66 | /** | ||
67 | * @typedef Eio_Version | ||
68 | * Represents the current version of EIO | ||
69 | */ | ||
70 | typedef struct _Eio_Version | ||
71 | { | ||
72 | int major; /**< Major version number */ | ||
73 | int minor; /**< Minor version number */ | ||
74 | int micro; /**< Micro version number */ | ||
75 | int revision; /**< Revision number */ | ||
76 | } Eio_Version; | ||
77 | |||
78 | EAPI extern Eio_Version *eio_version; | ||
79 | |||
80 | /** | ||
81 | * @defgroup Eio_Group Eio Reference API | ||
82 | * | ||
83 | * @brief This is the core asynchronous input/output operation | ||
84 | * | ||
85 | * All the functions in this group perform input/output operations | ||
86 | * in a separate thread using the infrastructure provided by | ||
87 | * Ecore_Thread and Eina, this means that all functions here are non-blocking. | ||
88 | * | ||
89 | * The functions displayed here are used to make basic file operations, like | ||
90 | * listing the content of a directory, creating a new directory, etc. | ||
91 | * | ||
92 | * @{ | ||
93 | */ | ||
94 | |||
95 | /** | ||
96 | * @enum _Eio_File_Op | ||
97 | * | ||
98 | * @brief Input/Output operations on files. | ||
99 | * | ||
100 | * This enum represents the operations that can be done. | ||
101 | */ | ||
102 | enum _Eio_File_Op | ||
103 | { | ||
104 | EIO_FILE_COPY, /**< I/O operation is about a specific file copy */ | ||
105 | EIO_FILE_MOVE, /**< I/O operation is about a specific file move */ | ||
106 | EIO_DIR_COPY, /**< I/O operation is about a specific directory copy */ | ||
107 | EIO_DIR_MOVE, /**< I/O operation is about a specific directory move */ | ||
108 | /** I/O operation is about destroying a path: | ||
109 | * source will point to base path to be destroyed, | ||
110 | * and dest will point to to path destroyed by this I/O | ||
111 | */ | ||
112 | EIO_UNLINK, | ||
113 | EIO_FILE_GETPWNAM, /**< I/O operation is trying to get uid from user name */ | ||
114 | EIO_FILE_GETGRNAM /**< I/O operation is trying to get gid from user name */ | ||
115 | }; | ||
116 | |||
117 | /** | ||
118 | * @typedef Eio_File_Op | ||
119 | * Input/Output operations on files. | ||
120 | */ | ||
121 | typedef enum _Eio_File_Op Eio_File_Op; | ||
122 | |||
123 | /** | ||
124 | * @typedef Eio_File | ||
125 | * Generic asynchronous I/O reference. | ||
126 | */ | ||
127 | typedef struct _Eio_File Eio_File; | ||
128 | |||
129 | /** | ||
130 | * @typedef Eio_Progress | ||
131 | * Progress information on a specific operation. | ||
132 | */ | ||
133 | typedef struct _Eio_Progress Eio_Progress; | ||
134 | |||
135 | typedef Eina_Bool (*Eio_Filter_Cb)(void *data, Eio_File *handler, const char *file); | ||
136 | typedef void (*Eio_Main_Cb)(void *data, Eio_File *handler, const char *file); | ||
137 | |||
138 | typedef Eina_Bool (*Eio_Filter_Direct_Cb)(void *data, Eio_File *handler, const Eina_File_Direct_Info *info); | ||
139 | typedef Eina_Bool (*Eio_Filter_Dir_Cb)(void *data, Eio_File *handler, Eina_File_Direct_Info *info); | ||
140 | typedef void (*Eio_Main_Direct_Cb)(void *data, Eio_File *handler, const Eina_File_Direct_Info *info); | ||
141 | |||
142 | typedef void (*Eio_Stat_Cb)(void *data, Eio_File *handler, const Eina_Stat *stat); | ||
143 | typedef void (*Eio_Progress_Cb)(void *data, Eio_File *handler, const Eio_Progress *info); | ||
144 | |||
145 | typedef void (*Eio_Eet_Open_Cb)(void *data, Eio_File *handler, Eet_File *file); | ||
146 | typedef void (*Eio_Open_Cb)(void *data, Eio_File *handler, Eina_File *file); | ||
147 | typedef Eina_Bool (*Eio_Filter_Map_Cb)(void *data, Eio_File *handler, void *map, size_t length); | ||
148 | typedef void (*Eio_Map_Cb)(void *data, Eio_File *handler, void *map, size_t length); | ||
149 | |||
150 | typedef void (*Eio_Done_Data_Cb)(void *data, Eio_File *handler, const char *read_data, unsigned int size); | ||
151 | typedef void (*Eio_Done_String_Cb)(void *data, Eio_File *handler, const char *xattr_string); | ||
152 | typedef void (*Eio_Done_Double_Cb)(void *data, Eio_File *handler, double xattr_double); | ||
153 | typedef void (*Eio_Done_Int_Cb)(void *data, Eio_File *handler, int i); | ||
154 | |||
155 | typedef void (*Eio_Done_ERead_Cb)(void *data, Eio_File *handler, void *decoded); | ||
156 | typedef void (*Eio_Done_Read_Cb)(void *data, Eio_File *handler, void *read_data, unsigned int size); | ||
157 | typedef void (*Eio_Done_Cb)(void *data, Eio_File *handler); | ||
158 | typedef void (*Eio_Error_Cb)(void *data, Eio_File *handler, int error); | ||
159 | typedef void (*Eio_Eet_Error_Cb)(void *data, Eio_File *handler, Eet_Error err); | ||
160 | |||
161 | /** | ||
162 | * @struct _Eio_Progress | ||
163 | * @brief Represents the current progress of the operation. | ||
164 | */ | ||
165 | struct _Eio_Progress | ||
166 | { | ||
167 | Eio_File_Op op; /**< I/O type */ | ||
168 | |||
169 | long long current; /**< Current step in the I/O operation */ | ||
170 | long long max; /**< Number of total steps to complete this I/O */ | ||
171 | float percent; /**< Percent done for the I/O operation */ | ||
172 | |||
173 | const char *source; /**< source of the I/O operation */ | ||
174 | const char *dest; /**< target of the I/O operation */ | ||
175 | }; | ||
176 | |||
177 | /** | ||
178 | * @brief List contents of a directory without locking your app. | ||
179 | * @param dir The directory to list. | ||
180 | * @param filter_cb Callback used to decide if the file will be passed to main_cb | ||
181 | * @param main_cb Callback called for each listed file if it was not filtered. | ||
182 | * @param done_cb Callback called when the ls operation is done. | ||
183 | * @param error_cb Callback called when either the directory could not be opened or the operation has been canceled. | ||
184 | * @param data Unmodified user data passed to callbacks | ||
185 | * @return A reference to the I/O operation. | ||
186 | * | ||
187 | * This function is responsible for listing the content of a directory without blocking your application. | ||
188 | * It's equivalent to the "ls" shell command. Every file will be passed to the | ||
189 | * filter_cb, so it's your job to decide if you want to pass the file to the | ||
190 | * main_cb or not. Return EINA_TRUE to pass it to the main_cb or EINA_FALSE to | ||
191 | * ignore it. | ||
192 | */ | ||
193 | EAPI Eio_File *eio_file_ls(const char *dir, | ||
194 | Eio_Filter_Cb filter_cb, | ||
195 | Eio_Main_Cb main_cb, | ||
196 | Eio_Done_Cb done_cb, | ||
197 | Eio_Error_Cb error_cb, | ||
198 | const void *data); | ||
199 | |||
200 | /** | ||
201 | * @brief List contents of a directory without locking your app. | ||
202 | * @param dir The directory to list. | ||
203 | * @param filter_cb Callback used to decide if the file will be passed to main_cb | ||
204 | * @param main_cb Callback called from the main loop for each accepted file (not filtered). | ||
205 | * @param done_cb Callback called from the main loop after the contents of the directory has been listed. | ||
206 | * @param error_cb Callback called from the main loop when either the directory could not be opened or the operation has been canceled. | ||
207 | * @param data Unmodified user data passed to callbacks | ||
208 | * @return A reference to the I/O operation. | ||
209 | * | ||
210 | * eio_file_direct_ls runs eina_file_direct_ls in a separate thread using | ||
211 | * ecore_thread_feedback_run. This prevents any blocking in your apps. | ||
212 | * Every file will be passed to the filter_cb, so it's your job to decide if you | ||
213 | * want to pass the file to the main_cb or not. Return EINA_TRUE to pass it to | ||
214 | * the main_cb or EINA_FALSE to ignore it. | ||
215 | */ | ||
216 | EAPI Eio_File *eio_file_direct_ls(const char *dir, | ||
217 | Eio_Filter_Direct_Cb filter_cb, | ||
218 | Eio_Main_Direct_Cb main_cb, | ||
219 | Eio_Done_Cb done_cb, | ||
220 | Eio_Error_Cb error_cb, | ||
221 | const void *data); | ||
222 | |||
223 | /** | ||
224 | * @brief List content of a directory without locking your app. | ||
225 | * @param dir The directory to list. | ||
226 | * @param filter_cb Callback used to decide if the file will be passed to main_cb | ||
227 | * @param main_cb Callback called from the main loop for each accepted file (not filtered). | ||
228 | * @param done_cb Callback called from the main loop after the contents of the directory has been listed. | ||
229 | * @param error_cb Callback called from the main loop when either the directory could not be opened or the operation has been canceled. | ||
230 | * @param data Unmodified user data passed to callbacks | ||
231 | * @return A reference to the I/O operation. | ||
232 | * | ||
233 | * Every file will be passed to the filter_cb, so it's your job to decide if you | ||
234 | * want to pass the file to the main_cb or not. Return EINA_TRUE to pass it to | ||
235 | * the main_cb or EINA_FALSE to ignore it. | ||
236 | * | ||
237 | */ | ||
238 | EAPI Eio_File *eio_file_stat_ls(const char *dir, | ||
239 | Eio_Filter_Direct_Cb filter_cb, | ||
240 | Eio_Main_Direct_Cb main_cb, | ||
241 | Eio_Done_Cb done_cb, | ||
242 | Eio_Error_Cb error_cb, | ||
243 | const void *data); | ||
244 | |||
245 | /** | ||
246 | * @brief List the content of a directory and all it's sub-content asynchronously | ||
247 | * @param dir The directory to list. | ||
248 | * @param filter_cb Callback used to decide if the file will be passed to main_cb | ||
249 | * @param main_cb Callback called from the main loop for each accepted file (not filtered). | ||
250 | * @param done_cb Callback called from the main loop after the contents of the directory has been listed. | ||
251 | * @param error_cb Callback called from the main loop when either the directory could not be opened or the operation has been canceled. | ||
252 | * @param data Unmodified user data passed to callbacks | ||
253 | * @return A reference to the I/O operation. | ||
254 | * | ||
255 | * eio_dir_stat_ls() runs eina_file_stat_ls() recursively in a separate thread using | ||
256 | * ecore_thread_feedback_run. This prevents any blocking in your apps. | ||
257 | * Every file will be passed to the | ||
258 | * filter_cb, so it's your job to decide if you want to pass the file to the | ||
259 | * main_cb or not. Return EINA_TRUE to pass it to the main_cb or EINA_FALSE to | ||
260 | * ignore it. | ||
261 | */ | ||
262 | EAPI Eio_File *eio_dir_stat_ls(const char *dir, | ||
263 | Eio_Filter_Direct_Cb filter_cb, | ||
264 | Eio_Main_Direct_Cb main_cb, | ||
265 | Eio_Done_Cb done_cb, | ||
266 | Eio_Error_Cb error_cb, | ||
267 | const void *data); | ||
268 | |||
269 | /** | ||
270 | * @brief List the content of a directory and all it's sub-content asynchronously | ||
271 | * @param dir The directory to list. | ||
272 | * @param filter_cb Callback used to decide if the file will be passed to main_cb | ||
273 | * @param main_cb Callback called from the main loop for each accepted file (not filtered). | ||
274 | * @param done_cb Callback called from the main loop after the contents of the directory has been listed. | ||
275 | * @param error_cb Callback called from the main loop when either the directory could not be opened or the operation has been canceled. | ||
276 | * @param data Unmodified user data passed to callbacks | ||
277 | * @return A reference to the I/O operation. | ||
278 | * | ||
279 | * eio_dir_direct_ls() runs eina_file_direct_ls() recursively in a separate thread using | ||
280 | * ecore_thread_feedback_run. This prevents any blocking in your apps. | ||
281 | * Every file will be passed to the filter_cb, so it's your job to decide if you | ||
282 | * want to pass the file to the main_cb or not. Return EINA_TRUE to pass it to | ||
283 | * the main_cb or EINA_FALSE to ignore it. | ||
284 | */ | ||
285 | EAPI Eio_File *eio_dir_direct_ls(const char *dir, | ||
286 | Eio_Filter_Dir_Cb filter_cb, | ||
287 | Eio_Main_Direct_Cb main_cb, | ||
288 | Eio_Done_Cb done_cb, | ||
289 | Eio_Error_Cb error_cb, | ||
290 | const void *data); | ||
291 | |||
292 | /** | ||
293 | * @brief Stat a file/directory. | ||
294 | * @param path The path to stat. | ||
295 | * @param done_cb Callback called from the main loop when stat was successfully called. | ||
296 | * @param error_cb Callback called from the main loop when stat failed or has been canceled. | ||
297 | * @param data Unmodified user data passed to callbacks | ||
298 | * @return A reference to the I/O operation. | ||
299 | * | ||
300 | * eio_file_direct_stat calls stat in another thread. This prevents any blocking in your apps. | ||
301 | */ | ||
302 | EAPI Eio_File *eio_file_direct_stat(const char *path, | ||
303 | Eio_Stat_Cb done_cb, | ||
304 | Eio_Error_Cb error_cb, | ||
305 | const void *data); | ||
306 | |||
307 | /** | ||
308 | * @brief Change right of a path. | ||
309 | * @param path The directory path to change access right. | ||
310 | * @param mode The permission to set, follow (mode & ~umask & 0777). | ||
311 | * @param done_cb Callback called when the operation is completed. | ||
312 | * @param error_cb Callback called from if something goes wrong. | ||
313 | * @param data Unmodified user data passed to callbacks. | ||
314 | * @return A reference to the I/O operation. | ||
315 | * | ||
316 | * Set a new permission of a path changing it to the mode passed as argument. | ||
317 | * It's equivalent to the chmod command. | ||
318 | */ | ||
319 | EAPI Eio_File *eio_file_chmod(const char *path, | ||
320 | mode_t mode, | ||
321 | Eio_Done_Cb done_cb, | ||
322 | Eio_Error_Cb error_cb, | ||
323 | const void *data); | ||
324 | |||
325 | /** | ||
326 | * @brief Change owner of a path. | ||
327 | * @param path The directory path to change owner. | ||
328 | * @param user The new user to set (can be NULL). | ||
329 | * @param group The new group to set (can be NULL). | ||
330 | * @param done_cb Callback called when the operation is completed. | ||
331 | * @param error_cb Callback called from if something goes wrong. | ||
332 | * @param data Unmodified user data passed to callbacks | ||
333 | * @return A reference to the I/O operation. | ||
334 | * | ||
335 | * This function will change the owner of a path, setting it to the user and | ||
336 | * group passed as argument. It's equivalent to the chown shell command. | ||
337 | */ | ||
338 | EAPI Eio_File *eio_file_chown(const char *path, | ||
339 | const char *user, | ||
340 | const char *group, | ||
341 | Eio_Done_Cb done_cb, | ||
342 | Eio_Error_Cb error_cb, | ||
343 | const void *data); | ||
344 | |||
345 | /** | ||
346 | * @brief Unlink a file/directory. | ||
347 | * @param path The path to unlink. | ||
348 | * @param done_cb Callback called when the operation is completed. | ||
349 | * @param error_cb Callback called from if something goes wrong. | ||
350 | * @param data Unmodified user data passed to callbacks. | ||
351 | * @return A reference to the I/O operation. | ||
352 | * | ||
353 | * This function will erase a file. | ||
354 | */ | ||
355 | EAPI Eio_File *eio_file_unlink(const char *path, | ||
356 | Eio_Done_Cb done_cb, | ||
357 | Eio_Error_Cb error_cb, | ||
358 | const void *data); | ||
359 | |||
360 | /** | ||
361 | * @brief Create a new directory. | ||
362 | * @param path The directory path to create. | ||
363 | * @param mode The permission to set, follow (mode & ~umask & 0777). | ||
364 | * @param done_cb Callback called when the operation is completed. | ||
365 | * @param error_cb Callback called from if something goes wrong. | ||
366 | * @param data Unmodified user data passed to callbacks | ||
367 | * @return A reference to the I/O operation. | ||
368 | * | ||
369 | * Creates a new directory using the mode provided. | ||
370 | */ | ||
371 | EAPI Eio_File *eio_file_mkdir(const char *path, | ||
372 | mode_t mode, | ||
373 | Eio_Done_Cb done_cb, | ||
374 | Eio_Error_Cb error_cb, | ||
375 | const void *data); | ||
376 | |||
377 | /** | ||
378 | * @brief Move a file asynchronously | ||
379 | * @param source Should be the name of the file to move the data from. | ||
380 | * @param dest Should be the name of the file to move the data to. | ||
381 | * @param progress_cb Callback called to know the progress of the move. | ||
382 | * @param done_cb Callback called when the move is done. | ||
383 | * @param error_cb Callback called when something goes wrong. | ||
384 | * @param data Unmodified user data passed to callbacks | ||
385 | * | ||
386 | * This function will copy a file from source to dest. It will try to use splice | ||
387 | * if possible, if not it will fallback to mmap/write. It will try to preserve | ||
388 | * access right, but not user/group identification. | ||
389 | */ | ||
390 | EAPI Eio_File *eio_file_move(const char *source, | ||
391 | const char *dest, | ||
392 | Eio_Progress_Cb progress_cb, | ||
393 | Eio_Done_Cb done_cb, | ||
394 | Eio_Error_Cb error_cb, | ||
395 | const void *data); | ||
396 | |||
397 | /** | ||
398 | * @brief Copy a file asynchronously | ||
399 | * @param source Should be the name of the file to copy the data from. | ||
400 | * @param dest Should be the name of the file to copy the data to. | ||
401 | * @param progress_cb Callback called to know the progress of the copy. | ||
402 | * @param done_cb Callback called when the copy is done. | ||
403 | * @param error_cb Callback called when something goes wrong. | ||
404 | * @param data Unmodified user data passed to callbacks | ||
405 | * | ||
406 | * This function will copy a file from source to dest. It will try to use splice | ||
407 | * if possible, if not it will fallback to mmap/write. It will try to preserve | ||
408 | * access right, but not user/group identification. | ||
409 | */ | ||
410 | EAPI Eio_File *eio_file_copy(const char *source, | ||
411 | const char *dest, | ||
412 | Eio_Progress_Cb progress_cb, | ||
413 | Eio_Done_Cb done_cb, | ||
414 | Eio_Error_Cb error_cb, | ||
415 | const void *data); | ||
416 | |||
417 | /** | ||
418 | * @brief Move a directory and it's content asynchronously | ||
419 | * @param source Should be the name of the directory to copy the data from. | ||
420 | * @param dest Should be the name of the directory to copy the data to. | ||
421 | * @param filter_cb Possible to deny the move of some files/directories. | ||
422 | * @param progress_cb Callback called to know the progress of the copy. | ||
423 | * @param done_cb Callback called when the copy is done. | ||
424 | * @param error_cb Callback called when something goes wrong. | ||
425 | * @param data Unmodified user data passed to callbacks | ||
426 | * | ||
427 | * This function will move a directory and all it's content from source to dest. | ||
428 | * It will try first to rename the directory, if not it will try to use splice | ||
429 | * if possible, if not it will fallback to mmap/write. | ||
430 | * It will try to preserve access right, but not user/group identity. | ||
431 | * Every file will be passed to the filter_cb, so it's your job to decide if you | ||
432 | * want to pass the file to the main_cb or not. Return EINA_TRUE to pass it to | ||
433 | * the main_cb or EINA_FALSE to ignore it. | ||
434 | * | ||
435 | * @note if a rename occur, the filter callback will not be called. | ||
436 | */ | ||
437 | EAPI Eio_File *eio_dir_move(const char *source, | ||
438 | const char *dest, | ||
439 | Eio_Filter_Direct_Cb filter_cb, | ||
440 | Eio_Progress_Cb progress_cb, | ||
441 | Eio_Done_Cb done_cb, | ||
442 | Eio_Error_Cb error_cb, | ||
443 | const void *data); | ||
444 | |||
445 | /** | ||
446 | * @brief Copy a directory and it's content asynchronously | ||
447 | * @param source Should be the name of the directory to copy the data from. | ||
448 | * @param dest Should be the name of the directory to copy the data to. | ||
449 | * @param filter_cb Possible to deny the move of some files/directories. | ||
450 | * @param progress_cb Callback called to know the progress of the copy. | ||
451 | * @param done_cb Callback called when the copy is done. | ||
452 | * @param error_cb Callback called when something goes wrong. | ||
453 | * @param data Unmodified user data passed to callbacks | ||
454 | * | ||
455 | * This function will copy a directory and all it's content from source to dest. | ||
456 | * It will try to use splice if possible, if not it will fallback to mmap/write. | ||
457 | * It will try to preserve access right, but not user/group identity. | ||
458 | * Every file will be passed to the filter_cb, so it's your job to decide if you | ||
459 | * want to pass the file to the main_cb or not. Return EINA_TRUE to pass it to | ||
460 | * the main_cb or EINA_FALSE to ignore it. | ||
461 | */ | ||
462 | EAPI Eio_File *eio_dir_copy(const char *source, | ||
463 | const char *dest, | ||
464 | Eio_Filter_Direct_Cb filter_cb, | ||
465 | Eio_Progress_Cb progress_cb, | ||
466 | Eio_Done_Cb done_cb, | ||
467 | Eio_Error_Cb error_cb, | ||
468 | const void *data); | ||
469 | |||
470 | /** | ||
471 | * @brief Remove a directory and it's content asynchronously | ||
472 | * @param path Should be the name of the directory to destroy. | ||
473 | * @param filter_cb Possible to deny the move of some files/directories. | ||
474 | * @param progress_cb Callback called to know the progress of the copy. | ||
475 | * @param done_cb Callback called when the copy is done. | ||
476 | * @param error_cb Callback called when something goes wrong. | ||
477 | * @param data Unmodified user data passed to callbacks | ||
478 | * | ||
479 | * This function will remove a directory and all it's content. | ||
480 | * Every file will be passed to the filter_cb, so it's your job to decide if you | ||
481 | * want to pass the file to the main_cb or not. Return EINA_TRUE to pass it to | ||
482 | * the main_cb or EINA_FALSE to ignore it. | ||
483 | */ | ||
484 | EAPI Eio_File *eio_dir_unlink(const char *path, | ||
485 | Eio_Filter_Direct_Cb filter_cb, | ||
486 | Eio_Progress_Cb progress_cb, | ||
487 | Eio_Done_Cb done_cb, | ||
488 | Eio_Error_Cb error_cb, | ||
489 | const void *data); | ||
490 | /** | ||
491 | * @} | ||
492 | */ | ||
493 | |||
494 | |||
495 | /** | ||
496 | * @defgroup Eio_Xattr Eio manipulation of eXtended attribute. | ||
497 | * | ||
498 | * @brief A set of function to manipulate data associated with a specific file | ||
499 | * | ||
500 | * The functions provided by this API are responsible to manage Extended | ||
501 | * attribute files. Like file authors, character encoding, checksum, etc. | ||
502 | * @{ | ||
503 | */ | ||
504 | |||
505 | /** | ||
506 | * @brief Assynchronously list all eXtended attribute | ||
507 | * @param path The path to get the eXtended attribute from. | ||
508 | * @param filter_cb Callback called in the thread to validate the eXtended attribute. | ||
509 | * @param main_cb Callback called in the main loop for each accepted eXtended attribute. | ||
510 | * @param done_cb Callback called in the main loop when the all the eXtended attribute have been listed. | ||
511 | * @param error_cb Callback called in the main loop when something goes wrong during the listing of the eXtended attribute. | ||
512 | * @param data Unmodified user data passed to callbacks | ||
513 | * @return A reference to the I/O operation. | ||
514 | */ | ||
515 | EAPI Eio_File *eio_file_xattr(const char *path, | ||
516 | Eio_Filter_Cb filter_cb, | ||
517 | Eio_Main_Cb main_cb, | ||
518 | Eio_Done_Cb done_cb, | ||
519 | Eio_Error_Cb error_cb, | ||
520 | const void *data); | ||
521 | |||
522 | /** | ||
523 | * @brief Define an extented attribute on a file/directory. | ||
524 | * @param path The path to set the attribute on. | ||
525 | * @param attribute The name of the attribute to define. | ||
526 | * @param xattr_int The value to link the attribute with. | ||
527 | * @param flags Wether to insert, replace or create the attribute. | ||
528 | * @param done_cb The callback called from the main loop when setxattr succeeded. | ||
529 | * @param error_cb The callback called from the main loop when setxattr failed. | ||
530 | * @param data Unmodified user data passed to callbacks | ||
531 | * @return A reference to the I/O operation. | ||
532 | * | ||
533 | * eio_file_xattr_int_set calls eina_xattr_int_set from another thread. This prevents blocking in your apps. If | ||
534 | * the writing succeeded, the done_cb will be called even if a cancel was requested, but came to late. | ||
535 | */ | ||
536 | EAPI Eio_File *eio_file_xattr_int_set(const char *path, | ||
537 | const char *attribute, | ||
538 | int xattr_int, | ||
539 | Eina_Xattr_Flags flags, | ||
540 | Eio_Done_Cb done_cb, | ||
541 | Eio_Error_Cb error_cb, | ||
542 | const void *data); | ||
543 | |||
544 | /** | ||
545 | * @brief Define an extented attribute on a file/directory. | ||
546 | * @param path The path to set the attribute on. | ||
547 | * @param attribute The name of the attribute to define. | ||
548 | * @param xattr_double The value to link the attribute with. | ||
549 | * @param flags Wether to insert, replace or create the attribute. | ||
550 | * @param done_cb The callback called from the main loop when setxattr succeeded. | ||
551 | * @param error_cb The callback called from the main loop when setxattr failed. | ||
552 | * @param data Unmodified user data passed to callbacks | ||
553 | * @return A reference to the I/O operation. | ||
554 | * | ||
555 | * eio_file_xattr_double_set calls eina_xattr_double_set from another thread. This prevents blocking in your apps. If | ||
556 | * the writing succeeded, the done_cb will be called even if a cancel was requested, but came to late. | ||
557 | */ | ||
558 | EAPI Eio_File *eio_file_xattr_double_set(const char *path, | ||
559 | const char *attribute, | ||
560 | double xattr_double, | ||
561 | Eina_Xattr_Flags flags, | ||
562 | Eio_Done_Cb done_cb, | ||
563 | Eio_Error_Cb error_cb, | ||
564 | const void *data); | ||
565 | /** | ||
566 | * @brief Define a string extented attribute on a file/directory. | ||
567 | * @param path The path to set the attribute on. | ||
568 | * @param attribute The name of the attribute to define. | ||
569 | * @param xattr_string The string to link the attribute with. | ||
570 | * @param flags Wether to insert, replace or create the attribute. | ||
571 | * @param done_cb The callback called from the main loop when setxattr succeeded. | ||
572 | * @param error_cb The callback called from the main loop when setxattr failed. | ||
573 | * @param data Unmodified user data passed to callbacks | ||
574 | * @return A reference to the I/O operation. | ||
575 | * | ||
576 | * eio_file_xattr_string_set calls eina_xattr_string_set from another thread. This prevents blocking in your apps. If | ||
577 | * the writing succeeded, the done_cb will be called even if a cancel was requested, but came to late. | ||
578 | */ | ||
579 | EAPI Eio_File *eio_file_xattr_string_set(const char *path, | ||
580 | const char *attribute, | ||
581 | const char *xattr_string, | ||
582 | Eina_Xattr_Flags flags, | ||
583 | Eio_Done_Cb done_cb, | ||
584 | Eio_Error_Cb error_cb, | ||
585 | const void *data); | ||
586 | /** | ||
587 | * @brief Define an extented attribute on a file/directory. | ||
588 | * @param path The path to set the attribute on. | ||
589 | * @param attribute The name of the attribute to define. | ||
590 | * @param xattr_data The data to link the attribute with. | ||
591 | * @param xattr_size The size of the data to set. | ||
592 | * @param flags Wether to insert, replace or create the attribute. | ||
593 | * @param done_cb The callback called from the main loop when setxattr succeeded. | ||
594 | * @param error_cb The callback called from the main loop when setxattr failed. | ||
595 | * @param data Unmodified user data passed to callbacks | ||
596 | * @return A reference to the I/O operation. | ||
597 | * | ||
598 | * eio_file_xattr_set calls setxattr from another thread. This prevents blocking in your apps. If | ||
599 | * the writing succeeded, the done_cb will be called even if a cancel was requested, but came to late. | ||
600 | */ | ||
601 | EAPI Eio_File *eio_file_xattr_set(const char *path, | ||
602 | const char *attribute, | ||
603 | const char *xattr_data, | ||
604 | unsigned int xattr_size, | ||
605 | Eina_Xattr_Flags flags, | ||
606 | Eio_Done_Cb done_cb, | ||
607 | Eio_Error_Cb error_cb, | ||
608 | const void *data); | ||
609 | |||
610 | /** | ||
611 | * @brief Retrieve the extended attribute of a file/directory. | ||
612 | * @param path The path to retrieve the extended attribute from. | ||
613 | * @param attribute The name of the attribute to retrieve. | ||
614 | * @param done_cb Callback called from the main loop when getxattr succeeded. | ||
615 | * @param error_cb Callback called from the main loop when getxattr failed or has been canceled. | ||
616 | * @param data Unmodified user data passed to callbacks | ||
617 | * @return A reference to the I/O operation. | ||
618 | * | ||
619 | * eio_file_xattr_get calls getxattr from another thread. This prevents blocking in your apps. | ||
620 | */ | ||
621 | EAPI Eio_File *eio_file_xattr_get(const char *path, | ||
622 | const char *attribute, | ||
623 | Eio_Done_Data_Cb done_cb, | ||
624 | Eio_Error_Cb error_cb, | ||
625 | const void *data); | ||
626 | /** | ||
627 | * @brief Retrieve a extended attribute of a file/directory. | ||
628 | * @param path The path to retrieve the extended attribute from. | ||
629 | * @param attribute The name of the attribute to retrieve. | ||
630 | * @param done_cb Callback called from the main loop when getxattr succeeded. | ||
631 | * @param error_cb Callback called from the main loop when getxattr failed or has been canceled. | ||
632 | * @param data Unmodified user data passed to callbacks | ||
633 | * @return A reference to the I/O operation. | ||
634 | * | ||
635 | * eio_file_xattr_int_get calls eina_xattr_int_get from another thread. This prevents blocking in your apps. | ||
636 | */ | ||
637 | EAPI Eio_File *eio_file_xattr_int_get(const char *path, | ||
638 | const char *attribute, | ||
639 | Eio_Done_Int_Cb done_cb, | ||
640 | Eio_Error_Cb error_cb, | ||
641 | const void *data); | ||
642 | /** | ||
643 | * @brief Retrieve a extended attribute of a file/directory. | ||
644 | * @param path The path to retrieve the extended attribute from. | ||
645 | * @param attribute The name of the attribute to retrieve. | ||
646 | * @param done_cb Callback called from the main loop when getxattr succeeded. | ||
647 | * @param error_cb Callback called from the main loop when getxattr failed or has been canceled. | ||
648 | * @param data Unmodified user data passed to callbacks | ||
649 | * @return A reference to the I/O operation. | ||
650 | * | ||
651 | * eio_file_xattr_double_get calls eina_xattr_double_get from another thread. This prevents blocking in your apps. | ||
652 | */ | ||
653 | EAPI Eio_File *eio_file_xattr_double_get(const char *path, | ||
654 | const char *attribute, | ||
655 | Eio_Done_Double_Cb done_cb, | ||
656 | Eio_Error_Cb error_cb, | ||
657 | const void *data); | ||
658 | /** | ||
659 | * @brief Retrieve a string extended attribute of a file/directory. | ||
660 | * @param path The path to retrieve the extended attribute from. | ||
661 | * @param attribute The name of the attribute to retrieve. | ||
662 | * @param done_cb Callback called from the main loop when getxattr succeeded. | ||
663 | * @param error_cb Callback called from the main loop when getxattr failed or has been canceled. | ||
664 | * @param data Unmodified user data passed to callbacks | ||
665 | * @return A reference to the I/O operation. | ||
666 | * | ||
667 | * eio_file_xattr_string_get calls eina_xattr_string_get from another thread. This prevents blocking in your apps. | ||
668 | */ | ||
669 | EAPI Eio_File *eio_file_xattr_string_get(const char *path, | ||
670 | const char *attribute, | ||
671 | Eio_Done_String_Cb done_cb, | ||
672 | Eio_Error_Cb error_cb, | ||
673 | const void *data); | ||
674 | |||
675 | /** | ||
676 | * @} | ||
677 | */ | ||
678 | |||
679 | /** | ||
680 | * @defgroup Eio_Helper Eio Reference helper API | ||
681 | * | ||
682 | * @brief This are helper provided around core Eio API. | ||
683 | * | ||
684 | * This set of functions do provide helper to work around data | ||
685 | * provided by Eio without the need to look at system header. | ||
686 | * | ||
687 | * @{ | ||
688 | */ | ||
689 | |||
690 | |||
691 | /** | ||
692 | * @brief Initialize eio and all it's required submodule. | ||
693 | * @return the current number of eio users. | ||
694 | */ | ||
695 | EAPI int eio_init(void); | ||
696 | |||
697 | /** | ||
698 | * @brief Shutdown eio and all it's submodule if possible. | ||
699 | * @return the number of pending users of eio. | ||
700 | */ | ||
701 | EAPI int eio_shutdown(void); | ||
702 | |||
703 | /** | ||
704 | * @brief Return the container during EIO operation | ||
705 | * @param ls The asynchronous I/O operation to retrieve container from. | ||
706 | * @return NULL if not available, a DIRP if it is. | ||
707 | * | ||
708 | * This is only available and make sense in the thread callback, not in | ||
709 | * the mainloop. | ||
710 | */ | ||
711 | EAPI void *eio_file_container_get(Eio_File *ls); | ||
712 | |||
713 | /** | ||
714 | * @brief Cancel any Eio_File. | ||
715 | * @param ls The asynchronous I/O operation to cancel. | ||
716 | * @return EINA_FALSE if the destruction is delayed, EINA_TRUE if it's done. | ||
717 | * | ||
718 | * This will cancel any kind of I/O operation and cleanup the mess. This means | ||
719 | * that it could take time to cancel an I/O. | ||
720 | */ | ||
721 | EAPI Eina_Bool eio_file_cancel(Eio_File *ls); | ||
722 | |||
723 | /** | ||
724 | * @brief Check if an Eio_File operation has been cancelled. | ||
725 | * @param ls The asynchronous I/O operation to check. | ||
726 | * @return EINA_TRUE if it was canceled, EINA_FALSE other wise. | ||
727 | * | ||
728 | * In case of an error it also return EINA_TRUE. | ||
729 | */ | ||
730 | EAPI Eina_Bool eio_file_check(Eio_File *ls); | ||
731 | |||
732 | /** | ||
733 | * @brief Associate data with the current filtered file. | ||
734 | * @param ls The Eio_File ls request currently calling the filter callback. | ||
735 | * @param key The key to associate data to. | ||
736 | * @param data The data to associate the data to. | ||
737 | * @param free_cb Optionally a function to call to free the associated data, | ||
738 | * @p data is passed as the callback data parameter. If no @free_cb is provided | ||
739 | * the user @p data remains untouched. | ||
740 | * @return EINA_TRUE if insertion was fine. | ||
741 | * | ||
742 | * This function can only be safely called from within the filter callback. | ||
743 | * If you don't need to copy the key around you can use @ref eio_file_associate_direct_add | ||
744 | */ | ||
745 | EAPI Eina_Bool eio_file_associate_add(Eio_File *ls, | ||
746 | const char *key, | ||
747 | const void *data, Eina_Free_Cb free_cb); | ||
748 | |||
749 | /** | ||
750 | * @brief Associate data with the current filtered file. | ||
751 | * @param ls The Eio_File ls request currently calling the filter callback. | ||
752 | * @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). | ||
753 | * @param data The data to associate the data to. | ||
754 | * @param free_cb The function to call to free the associated data, @p free will be called if not specified. | ||
755 | * @return EINA_TRUE if insertion was fine. | ||
756 | * | ||
757 | * This function can only be safely called from within the filter callback. | ||
758 | * If you need eio to make a proper copy of the @p key to be safe use | ||
759 | * @ref eio_file_associate_add instead. | ||
760 | */ | ||
761 | EAPI Eina_Bool eio_file_associate_direct_add(Eio_File *ls, | ||
762 | const char *key, | ||
763 | const void *data, Eina_Free_Cb free_cb); | ||
764 | |||
765 | /** | ||
766 | * @brief Get the data associated during the filter callback inside the main loop | ||
767 | * @param ls The Eio_File ls request currently calling the notify callback. | ||
768 | * @param key The key pointing to the data to retrieve. | ||
769 | * @return the data associated with the key or @p NULL if not found. | ||
770 | */ | ||
771 | EAPI void *eio_file_associate_find(Eio_File *ls, const char *key); | ||
772 | |||
773 | /** | ||
774 | * @brief get access time from a Eina_Stat | ||
775 | * @param stat the structure to get the atime from | ||
776 | * @return the last accessed time | ||
777 | * | ||
778 | * This take care of doing type conversion to match rest of EFL time API. | ||
779 | * @note some filesystem don't update that information. | ||
780 | */ | ||
781 | static inline double eio_file_atime(const Eina_Stat *stat); | ||
782 | |||
783 | /** | ||
784 | * @brief get modification time from a Eina_Stat | ||
785 | * @param stat the structure to get the mtime from | ||
786 | * @return the last modification time | ||
787 | * | ||
788 | * This take care of doing type conversion to match rest of EFL time API. | ||
789 | */ | ||
790 | static inline double eio_file_mtime(const Eina_Stat *stat); | ||
791 | |||
792 | /** | ||
793 | * @brief get the size of the file described in Eina_Stat | ||
794 | * @param stat the structure to get the size from | ||
795 | * @return the size of the file | ||
796 | */ | ||
797 | static inline long long eio_file_size(const Eina_Stat *stat); | ||
798 | |||
799 | /** | ||
800 | * @brief tell if the stated path was a directory or not. | ||
801 | * @param stat the structure to get the size from | ||
802 | * @return EINA_TRUE, if it was. | ||
803 | */ | ||
804 | static inline Eina_Bool eio_file_is_dir(const Eina_Stat *stat); | ||
805 | |||
806 | /** | ||
807 | * @brief tell if the stated path was a link or not. | ||
808 | * @param stat the structure to get the size from | ||
809 | * @return EINA_TRUE, if it was. | ||
810 | */ | ||
811 | static inline Eina_Bool eio_file_is_lnk(const Eina_Stat *stat); | ||
812 | |||
813 | /** | ||
814 | * @} | ||
815 | */ | ||
816 | |||
817 | /** | ||
818 | * | ||
819 | */ | ||
820 | |||
821 | /** | ||
822 | * @defgroup Eio_Map Manipulate an Eina_File asynchronously | ||
823 | * | ||
824 | * @brief This function help manipulating file asynchronously. | ||
825 | * | ||
826 | * This set of function work on top of Eina_File and Ecore_Thread to | ||
827 | * do basic operations in a file, like openning, closing and mapping a file to | ||
828 | * memory. | ||
829 | * @{ | ||
830 | */ | ||
831 | |||
832 | /** | ||
833 | * @brief Assynchronously open a file. | ||
834 | * @param name The file to open. | ||
835 | * @param shared If it's a shared memory file. | ||
836 | * @param open_cb Callback called in the main loop when the file has been successfully opened. | ||
837 | * @param error_cb Callback called in the main loop when the file couldn't be opened. | ||
838 | * @param data Unmodified user data passed to callbacks | ||
839 | * @return Pointer to the file if successfull or NULL otherwise. | ||
840 | * | ||
841 | */ | ||
842 | EAPI Eio_File *eio_file_open(const char *name, Eina_Bool shared, | ||
843 | Eio_Open_Cb open_cb, | ||
844 | Eio_Error_Cb error_cb, | ||
845 | const void *data); | ||
846 | |||
847 | /** | ||
848 | * @brief Assynchronously close a file. | ||
849 | * @param f The file to close. | ||
850 | * @param done_cb Callback called in the main loop when the file has been successfully closed. | ||
851 | * @param error_cb Callback called in the main loop when the file couldn't be closed. | ||
852 | * @param data Unmodified user data passed to callbacks | ||
853 | * @return Pointer to the file if successfull or NULL otherwise. | ||
854 | */ | ||
855 | EAPI Eio_File *eio_file_close(Eina_File *f, | ||
856 | Eio_Done_Cb done_cb, | ||
857 | Eio_Error_Cb error_cb, | ||
858 | const void *data); | ||
859 | |||
860 | /** | ||
861 | * @brief Assynchronously map a file in memory. | ||
862 | * @param f The file to map. | ||
863 | * @param rule The rule to apply to the map. | ||
864 | * @param filter_cb Callback called in the thread to validate the content of the map. | ||
865 | * @param map_cb Callback called in the main loop when the file has been successfully mapped. | ||
866 | * @param error_cb Callback called in the main loop when the file can't be mapped. | ||
867 | * @param data Unmodified user data passed to callbacks | ||
868 | * @return Pointer to the file if successfull or NULL otherwise. | ||
869 | * | ||
870 | * The container of the Eio_File is the Eina_File. | ||
871 | */ | ||
872 | EAPI Eio_File *eio_file_map_all(Eina_File *f, | ||
873 | Eina_File_Populate rule, | ||
874 | Eio_Filter_Map_Cb filter_cb, | ||
875 | Eio_Map_Cb map_cb, | ||
876 | Eio_Error_Cb error_cb, | ||
877 | const void *data); | ||
878 | |||
879 | /** | ||
880 | * @brief Assynchronously map a part of a file in memory. | ||
881 | * @param f The file to map. | ||
882 | * @param rule The rule to apply to the map. | ||
883 | * @param offset The offset inside the file | ||
884 | * @param length The length of the memory to map | ||
885 | * @param filter_cb Callback called in the thread to validate the content of the map. | ||
886 | * @param map_cb Callback called in the main loop when the file has been successfully mapped. | ||
887 | * @param error_cb Callback called in the main loop when the file can't be mapped. | ||
888 | * @param data Unmodified user data passed to callbacks | ||
889 | * @return Pointer to the file if successfull or NULL otherwise. | ||
890 | * | ||
891 | * The container of the Eio_File is the Eina_File. | ||
892 | */ | ||
893 | EAPI Eio_File *eio_file_map_new(Eina_File *f, | ||
894 | Eina_File_Populate rule, | ||
895 | unsigned long int offset, | ||
896 | unsigned long int length, | ||
897 | Eio_Filter_Map_Cb filter_cb, | ||
898 | Eio_Map_Cb map_cb, | ||
899 | Eio_Error_Cb error_cb, | ||
900 | const void *data); | ||
901 | |||
902 | /** | ||
903 | * @} | ||
904 | */ | ||
905 | |||
906 | /** | ||
907 | * @defgroup Eio_Eet Eio asynchronous API for Eet file. | ||
908 | * | ||
909 | * @brief This set of functions help in the asynchronous use of Eet | ||
910 | * | ||
911 | * @{ | ||
912 | */ | ||
913 | |||
914 | /** | ||
915 | * @brief Open an eet file on disk, and returns a handle to it asynchronously. | ||
916 | * @param filename The file path to the eet file. eg: @c "/tmp/file.eet". | ||
917 | * @param mode The mode for opening. Either EET_FILE_MODE_READ, | ||
918 | * EET_FILE_MODE_WRITE or EET_FILE_MODE_READ_WRITE. | ||
919 | * @param eet_cb The callback to call when the file has been successfully opened. | ||
920 | * @param error_cb Callback called in the main loop when the file can't be opened. | ||
921 | * @param data Unmodified user data passed to callbacks | ||
922 | * @return NULL in case of a failure. | ||
923 | * | ||
924 | * This function calls eet_open() from another thread using Ecore_Thread. | ||
925 | */ | ||
926 | EAPI Eio_File *eio_eet_open(const char *filename, | ||
927 | Eet_File_Mode mode, | ||
928 | Eio_Eet_Open_Cb eet_cb, | ||
929 | Eio_Error_Cb error_cb, | ||
930 | const void *data); | ||
931 | /** | ||
932 | * @brief Close an eet file handle and flush pending writes asynchronously. | ||
933 | * @param ef A valid eet file handle. | ||
934 | * @param done_cb Callback called from the main loop when the file has been closed. | ||
935 | * @param error_cb Callback called in the main loop when the file can't be closed. | ||
936 | * @param data Unmodified user data passed to callbacks | ||
937 | * @return NULL in case of a failure. | ||
938 | * | ||
939 | * This function will call eet_close() from another thread by | ||
940 | * using Ecore_Thread. You should assume that the Eet_File is dead after this | ||
941 | * function is called. | ||
942 | */ | ||
943 | EAPI Eio_File *eio_eet_close(Eet_File *ef, | ||
944 | Eio_Done_Cb done_cb, | ||
945 | Eio_Eet_Error_Cb error_cb, | ||
946 | const void *data); | ||
947 | |||
948 | /** | ||
949 | * @brief Sync content of an eet file handle, flushing pending writes asynchronously. | ||
950 | * @param ef A valid eet file handle. | ||
951 | * @param done_cb Callback called from the main loop when the file has been synced. | ||
952 | * @param error_cb Callback called in the main loop when the file can't be synced. | ||
953 | * @param data Unmodified user data passed to callbacks | ||
954 | * @return NULL in case of a failure. | ||
955 | * | ||
956 | * This function will call eet_flush() from another thread. As long as the done_cb or | ||
957 | * error_cb haven't be called, you must keep @p ef open. | ||
958 | */ | ||
959 | EAPI Eio_File *eio_eet_sync(Eet_File *ef, | ||
960 | Eio_Done_Cb done_cb, | ||
961 | Eio_Eet_Error_Cb error_cb, | ||
962 | const void *data); | ||
963 | |||
964 | /** | ||
965 | * @brief Write a data structure from memory and store in an eet file | ||
966 | * using a cipher asynchronously. | ||
967 | * @param ef The eet file handle to write to. | ||
968 | * @param edd The data descriptor to use when encoding. | ||
969 | * @param name The key to store the data under in the eet file. | ||
970 | * @param cipher_key The key to use as cipher. | ||
971 | * @param write_data A pointer to the data structure to save and encode. | ||
972 | * @param compress Compression flags for storage. | ||
973 | * @param done_cb Callback called from the main loop when the data has been put in the Eet_File. | ||
974 | * @param error_cb Callback called in the main loop when the file can't be written. | ||
975 | * @param user_data Private data given to each callback. | ||
976 | * @return NULL in case of a failure. | ||
977 | */ | ||
978 | EAPI Eio_File *eio_eet_data_write_cipher(Eet_File *ef, | ||
979 | Eet_Data_Descriptor *edd, | ||
980 | const char *name, | ||
981 | const char *cipher_key, | ||
982 | void *write_data, | ||
983 | int compress, | ||
984 | Eio_Done_Int_Cb done_cb, | ||
985 | Eio_Error_Cb error_cb, | ||
986 | const void *user_data); | ||
987 | |||
988 | /** | ||
989 | * @brief Read a data structure from an eet file and decodes it using a cipher asynchronously. | ||
990 | * @param ef The eet file handle to read from. | ||
991 | * @param edd The data descriptor handle to use when decoding. | ||
992 | * @param name The key the data is stored under in the eet file. | ||
993 | * @param cipher_key The key to use as cipher. | ||
994 | * @param done_cb Callback called from the main loop when the data has been read and decoded. | ||
995 | * @param error_cb Callback called in the main loop when the data can't be read. | ||
996 | * @param data Unmodified user data passed to callbacks | ||
997 | * @return NULL in case of a failure. | ||
998 | */ | ||
999 | EAPI Eio_File *eio_eet_data_read_cipher(Eet_File *ef, | ||
1000 | Eet_Data_Descriptor *edd, | ||
1001 | const char *name, | ||
1002 | const char *cipher_key, | ||
1003 | Eio_Done_ERead_Cb done_cb, | ||
1004 | Eio_Error_Cb error_cb, | ||
1005 | const void *data); | ||
1006 | |||
1007 | /** | ||
1008 | * @brief Write image data to the named key in an eet file asynchronously. | ||
1009 | * @param ef A valid eet file handle opened for writing. | ||
1010 | * @param name Name of the entry. eg: "/base/file_i_want". | ||
1011 | * @param cipher_key The key to use as cipher. | ||
1012 | * @param write_data A pointer to the image pixel data. | ||
1013 | * @param w The width of the image in pixels. | ||
1014 | * @param h The height of the image in pixels. | ||
1015 | * @param alpha The alpha channel flag. | ||
1016 | * @param compress The compression amount. | ||
1017 | * @param quality The quality encoding amount. | ||
1018 | * @param lossy The lossiness flag. | ||
1019 | * @param done_cb Callback called from the main loop when the data has been put in the Eet_File. | ||
1020 | * @param error_cb Callback called in the main loop when the file can't be written. | ||
1021 | * @param user_data Private data given to each callback. | ||
1022 | * @return NULL in case of a failure. | ||
1023 | */ | ||
1024 | EAPI Eio_File *eio_eet_data_image_write_cipher(Eet_File *ef, | ||
1025 | const char *name, | ||
1026 | const char *cipher_key, | ||
1027 | void *write_data, | ||
1028 | unsigned int w, | ||
1029 | unsigned int h, | ||
1030 | int alpha, | ||
1031 | int compress, | ||
1032 | int quality, | ||
1033 | int lossy, | ||
1034 | Eio_Done_Int_Cb done_cb, | ||
1035 | Eio_Error_Cb error_cb, | ||
1036 | const void *user_data); | ||
1037 | |||
1038 | /** | ||
1039 | * @brief Read a specified entry from an eet file and return data | ||
1040 | * @param ef A valid eet file handle opened for reading. | ||
1041 | * @param name Name of the entry. eg: "/base/file_i_want". | ||
1042 | * @param done_cb Callback called from the main loop when the data has been read. | ||
1043 | * @param error_cb Callback called in the main loop when the data can't be read. | ||
1044 | * @param data Unmodified user data passed to callbacks | ||
1045 | * @return NULL in case of a failure. | ||
1046 | */ | ||
1047 | EAPI Eio_File *eio_eet_read_direct(Eet_File *ef, | ||
1048 | const char *name, | ||
1049 | Eio_Done_Data_Cb done_cb, | ||
1050 | Eio_Error_Cb error_cb, | ||
1051 | const void *data); | ||
1052 | |||
1053 | /** | ||
1054 | * @brief Read a specified entry from an eet file and return data | ||
1055 | * @param ef A valid eet file handle opened for reading. | ||
1056 | * @param name Name of the entry. eg: "/base/file_i_want". | ||
1057 | * @param cipher_key The key to use as cipher. | ||
1058 | * @param done_cb Callback called from the main loop when the data has been read. | ||
1059 | * @param error_cb Callback called in the main loop when the data can't be read. | ||
1060 | * @param data Unmodified user data passed to callbacks | ||
1061 | * @return NULL in case of a failure. | ||
1062 | */ | ||
1063 | EAPI Eio_File *eio_eet_read_cipher(Eet_File *ef, | ||
1064 | const char *name, | ||
1065 | const char *cipher_key, | ||
1066 | Eio_Done_Read_Cb done_cb, | ||
1067 | Eio_Error_Cb error_cb, | ||
1068 | const void *data); | ||
1069 | |||
1070 | /** | ||
1071 | * @brief Write a specified entry to an eet file handle using a cipher. | ||
1072 | * @param ef A valid eet file handle opened for writing. | ||
1073 | * @param name Name of the entry. eg: "/base/file_i_want". | ||
1074 | * @param write_data Pointer to the data to be stored. | ||
1075 | * @param size Length in bytes in the data to be stored. | ||
1076 | * @param compress Compression flags (1 == compress, 0 = don't compress). | ||
1077 | * @param cipher_key The key to use as cipher. | ||
1078 | * @param done_cb Callback called from the main loop when the data has been put in the Eet_File. | ||
1079 | * @param error_cb Callback called in the main loop when the file can't be written. | ||
1080 | * @param user_data Private data given to each callback. | ||
1081 | * @return NULL in case of a failure. | ||
1082 | */ | ||
1083 | EAPI Eio_File *eio_eet_write_cipher(Eet_File *ef, | ||
1084 | const char *name, | ||
1085 | void *write_data, | ||
1086 | int size, | ||
1087 | int compress, | ||
1088 | const char *cipher_key, | ||
1089 | Eio_Done_Int_Cb done_cb, | ||
1090 | Eio_Error_Cb error_cb, | ||
1091 | const void *user_data); | ||
1092 | |||
1093 | /** | ||
1094 | * @} | ||
1095 | */ | ||
1096 | |||
1097 | /** | ||
1098 | * @defgroup Eio_Monitor Eio file and directory monitoring API | ||
1099 | * | ||
1100 | * @brief These function monitor changes in directories and files | ||
1101 | * | ||
1102 | * These functions use the best available method to monitor changes on a specified directory | ||
1103 | * or file. They send ecore events when changes occur, and they maintain internal refcounts to | ||
1104 | * reduce resource consumption on duplicate monitor targets. | ||
1105 | * | ||
1106 | * @{ | ||
1107 | */ | ||
1108 | |||
1109 | EAPI extern int EIO_MONITOR_FILE_CREATED; /**< A new file was created in a watched directory */ | ||
1110 | EAPI extern int EIO_MONITOR_FILE_DELETED; /**< A watched file was deleted, or a file in a watched directory was deleted */ | ||
1111 | EAPI extern int EIO_MONITOR_FILE_MODIFIED; /**< A file was modified in a watched directory */ | ||
1112 | EAPI extern int EIO_MONITOR_FILE_CLOSED; /**< A file was closed in a watched directory. This event is never sent on Windows */ | ||
1113 | EAPI extern int EIO_MONITOR_DIRECTORY_CREATED; /**< A new directory was created in a watched directory */ | ||
1114 | EAPI extern int EIO_MONITOR_DIRECTORY_DELETED; /**< A directory has been deleted: this can be either a watched directory or one of its subdirectories */ | ||
1115 | EAPI extern int EIO_MONITOR_DIRECTORY_MODIFIED; /**< A directory has been modified in a watched directory */ | ||
1116 | EAPI extern int EIO_MONITOR_DIRECTORY_CLOSED; /**< A directory has been closed in a watched directory. This event is never sent on Windows */ | ||
1117 | 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 */ | ||
1118 | EAPI extern int EIO_MONITOR_SELF_DELETED; /**< The monitored path has been removed */ | ||
1119 | EAPI extern int EIO_MONITOR_ERROR; /**< During operation the monitor failed and will no longer work. eio_monitor_del must be called on it. */ | ||
1120 | |||
1121 | typedef struct _Eio_Monitor Eio_Monitor; | ||
1122 | |||
1123 | typedef struct _Eio_Monitor_Error Eio_Monitor_Error; | ||
1124 | typedef struct _Eio_Monitor_Event Eio_Monitor_Event; | ||
1125 | |||
1126 | struct _Eio_Monitor_Error | ||
1127 | { | ||
1128 | Eio_Monitor *monitor; | ||
1129 | int error; | ||
1130 | }; | ||
1131 | |||
1132 | struct _Eio_Monitor_Event | ||
1133 | { | ||
1134 | Eio_Monitor *monitor; | ||
1135 | const char *filename; | ||
1136 | }; | ||
1137 | |||
1138 | /** | ||
1139 | * @brief Adds a file/directory to monitor (inotify mechanism) | ||
1140 | * @param path file/directory to monitor | ||
1141 | * @return NULL in case of a failure or a pointer to the monitor in case of | ||
1142 | * success. | ||
1143 | * | ||
1144 | * This function will add the given path to its internal | ||
1145 | * list of files to monitor. It utilizes the inotify mechanism | ||
1146 | * introduced in kernel 2.6.13 for passive monitoring. | ||
1147 | */ | ||
1148 | EAPI Eio_Monitor *eio_monitor_add(const char *path); | ||
1149 | |||
1150 | /** | ||
1151 | * @brief Adds a file/directory to monitor | ||
1152 | * @param path file/directory to monitor | ||
1153 | * @return NULL in case of a failure or a pointer to the monitor in case of | ||
1154 | * success. | ||
1155 | * @warning Do NOT pass non-stringshared strings to this function! | ||
1156 | * If you don't know what this means, use eio_monitor_add(). | ||
1157 | * | ||
1158 | * This fuction is just like eio_monitor_add(), however the string passed by | ||
1159 | * argument must be created using eina_stringshare_add(). | ||
1160 | */ | ||
1161 | EAPI Eio_Monitor *eio_monitor_stringshared_add(const char *path); | ||
1162 | |||
1163 | /** | ||
1164 | * @brief Deletes a path from the “watched” list | ||
1165 | * @param monitor The Eio_Monitor you want to stop watching. | ||
1166 | * It can only be an Eio_Monitor returned to you from calling | ||
1167 | * eio_monitor_add() or eio_monitor_stringshared_add() | ||
1168 | */ | ||
1169 | EAPI void eio_monitor_del(Eio_Monitor *monitor); | ||
1170 | |||
1171 | /** | ||
1172 | * @brief returns the path being watched by the given | ||
1173 | * Eio_Monitor. | ||
1174 | * @param monitor Eio_Monitor to return the path of | ||
1175 | * @return The stringshared path belonging to @p monitor | ||
1176 | */ | ||
1177 | EAPI const char *eio_monitor_path_get(Eio_Monitor *monitor); | ||
1178 | |||
1179 | /** | ||
1180 | * @} | ||
1181 | */ | ||
1182 | |||
1183 | #include "eio_inline_helper.x" | ||
1184 | |||
1185 | #ifdef __cplusplus | ||
1186 | } | ||
1187 | #endif | ||
1188 | |||
1189 | |||
1190 | #endif | ||
diff --git a/src/lib/eio/eio_dir.c b/src/lib/eio/eio_dir.c new file mode 100644 index 0000000000..71cc3a0540 --- /dev/null +++ b/src/lib/eio/eio_dir.c | |||
@@ -0,0 +1,1001 @@ | |||
1 | /* EIO - EFL data type library | ||
2 | * Copyright (C) 2010 Enlightenment Developers: | ||
3 | * Cedric Bail <cedric.bail@free.fr> | ||
4 | * | ||
5 | * This library is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU Lesser General Public | ||
7 | * License as published by the Free Software Foundation; either | ||
8 | * version 2.1 of the License, or (at your option) any later version. | ||
9 | * | ||
10 | * This library is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * Lesser General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Lesser General Public | ||
16 | * License along with this library; | ||
17 | * if not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | #include "eio_private.h" | ||
21 | #include "Eio.h" | ||
22 | |||
23 | /*============================================================================* | ||
24 | * Local * | ||
25 | *============================================================================*/ | ||
26 | |||
27 | /** | ||
28 | * @cond LOCAL | ||
29 | */ | ||
30 | |||
31 | static int | ||
32 | eio_strcmp(const void *a, const void *b) | ||
33 | { | ||
34 | return strcmp(a, b); | ||
35 | } | ||
36 | static Eina_Bool | ||
37 | _eio_dir_recursive_progress(Eio_Dir_Copy *copy, Eio_File *handler, const Eina_File_Direct_Info *info) | ||
38 | { | ||
39 | if (copy->filter_cb && !copy->filter_cb(©->progress.common.data, handler, info)) | ||
40 | return EINA_FALSE; | ||
41 | |||
42 | switch (info->type) | ||
43 | { | ||
44 | case EINA_FILE_UNKNOWN: | ||
45 | eio_file_thread_error(©->progress.common, handler->thread); | ||
46 | return EINA_FALSE; | ||
47 | case EINA_FILE_LNK: | ||
48 | copy->links = eina_list_append(copy->links, eina_stringshare_add(info->path)); | ||
49 | break; | ||
50 | case EINA_FILE_DIR: | ||
51 | copy->dirs = eina_list_append(copy->dirs, eina_stringshare_add(info->path)); | ||
52 | break; | ||
53 | default: | ||
54 | copy->files = eina_list_append(copy->files, eina_stringshare_add(info->path)); | ||
55 | break; | ||
56 | } | ||
57 | |||
58 | return EINA_TRUE; | ||
59 | } | ||
60 | |||
61 | static Eina_Bool | ||
62 | _eio_file_recursiv_ls(Ecore_Thread *thread, | ||
63 | Eio_File *common, | ||
64 | Eio_Filter_Direct_Cb filter_cb, | ||
65 | Eina_Iterator *(*Eina_File_Ls)(const char *target), | ||
66 | void *data, | ||
67 | const char *target) | ||
68 | { | ||
69 | Eina_File_Direct_Info *info; | ||
70 | Eina_Iterator *it = NULL; | ||
71 | Eina_List *dirs = NULL; | ||
72 | const char *dir; | ||
73 | |||
74 | it = Eina_File_Ls(target); | ||
75 | if (!it) | ||
76 | { | ||
77 | eio_file_thread_error(common, thread); | ||
78 | return EINA_FALSE; | ||
79 | } | ||
80 | |||
81 | eio_file_container_set(common, eina_iterator_container_get(it)); | ||
82 | |||
83 | EINA_ITERATOR_FOREACH(it, info) | ||
84 | { | ||
85 | Eina_Bool filter = EINA_TRUE; | ||
86 | _eio_stat_t buffer; | ||
87 | |||
88 | switch (info->type) | ||
89 | { | ||
90 | case EINA_FILE_DIR: | ||
91 | if (_eio_lstat(info->path, &buffer) != 0) | ||
92 | continue; | ||
93 | |||
94 | if (S_ISLNK(buffer.st_mode)) | ||
95 | info->type = EINA_FILE_LNK; | ||
96 | default: | ||
97 | break; | ||
98 | } | ||
99 | |||
100 | filter = filter_cb(data, common, info); | ||
101 | if (filter && info->type == EINA_FILE_DIR) | ||
102 | dirs = eina_list_append(dirs, eina_stringshare_add(info->path)); | ||
103 | |||
104 | if (ecore_thread_check(thread)) | ||
105 | goto on_error; | ||
106 | } | ||
107 | |||
108 | eio_file_container_set(common, NULL); | ||
109 | |||
110 | eina_iterator_free(it); | ||
111 | it = NULL; | ||
112 | |||
113 | EINA_LIST_FREE(dirs, dir) | ||
114 | { | ||
115 | Eina_Bool err; | ||
116 | |||
117 | err = !_eio_file_recursiv_ls(thread, common, filter_cb, Eina_File_Ls, data, dir); | ||
118 | |||
119 | eina_stringshare_del(dir); | ||
120 | if (err) goto on_error; | ||
121 | } | ||
122 | |||
123 | return EINA_TRUE; | ||
124 | |||
125 | on_error: | ||
126 | if (it) eina_iterator_free(it); | ||
127 | |||
128 | EINA_LIST_FREE(dirs, dir) | ||
129 | eina_stringshare_del(dir); | ||
130 | |||
131 | return EINA_FALSE; | ||
132 | } | ||
133 | |||
134 | |||
135 | static Eina_Bool | ||
136 | _eio_dir_recursiv_ls(Ecore_Thread *thread, Eio_Dir_Copy *copy, const char *target) | ||
137 | { | ||
138 | if (!_eio_file_recursiv_ls(thread, ©->progress.common, | ||
139 | (Eio_Filter_Direct_Cb) _eio_dir_recursive_progress, | ||
140 | eina_file_stat_ls, | ||
141 | copy, target)) | ||
142 | return EINA_FALSE; | ||
143 | |||
144 | return EINA_TRUE; | ||
145 | } | ||
146 | |||
147 | static Eina_Bool | ||
148 | _eio_dir_init(Ecore_Thread *thread, | ||
149 | long long *step, long long *count, | ||
150 | int *length_source, int *length_dest, | ||
151 | Eio_Dir_Copy *order, | ||
152 | Eio_File_Progress *progress) | ||
153 | { | ||
154 | struct stat buffer; | ||
155 | |||
156 | /* notify main thread of the amount of work todo */ | ||
157 | *step = 0; | ||
158 | *count = eina_list_count(order->files) | ||
159 | + eina_list_count(order->dirs) * 2 | ||
160 | + eina_list_count(order->links); | ||
161 | eio_progress_send(thread, &order->progress, *step, *count); | ||
162 | |||
163 | /* sort the content, so we create the directory in the right order */ | ||
164 | order->dirs = eina_list_sort(order->dirs, -1, eio_strcmp); | ||
165 | order->files = eina_list_sort(order->files, -1, eio_strcmp); | ||
166 | order->links = eina_list_sort(order->links, -1, eio_strcmp); | ||
167 | |||
168 | /* prepare stuff */ | ||
169 | *length_source = eina_stringshare_strlen(order->progress.source); | ||
170 | *length_dest = eina_stringshare_strlen(order->progress.dest); | ||
171 | |||
172 | memcpy(progress, &order->progress, sizeof (Eio_File_Progress)); | ||
173 | progress->source = NULL; | ||
174 | progress->dest = NULL; | ||
175 | |||
176 | /* create destination dir if not available */ | ||
177 | if (stat(order->progress.dest, &buffer) != 0) | ||
178 | { | ||
179 | if (stat(order->progress.source, &buffer) != 0) | ||
180 | { | ||
181 | eio_file_thread_error(&order->progress.common, thread); | ||
182 | return EINA_FALSE; | ||
183 | } | ||
184 | |||
185 | if (mkdir(order->progress.dest, buffer.st_mode) != 0) | ||
186 | { | ||
187 | eio_file_thread_error(&order->progress.common, thread); | ||
188 | return EINA_FALSE; | ||
189 | } | ||
190 | } | ||
191 | |||
192 | return EINA_TRUE; | ||
193 | } | ||
194 | |||
195 | static void | ||
196 | _eio_dir_target(Eio_Dir_Copy *order, char *target, const char *dir, int length_source, int length_dest) | ||
197 | { | ||
198 | int length; | ||
199 | |||
200 | length = eina_stringshare_strlen(dir); | ||
201 | |||
202 | memcpy(target, order->progress.dest, length_dest); | ||
203 | target[length_dest] = '/'; | ||
204 | memcpy(target + length_dest + 1, dir + length_source, length - length_source + 1); | ||
205 | } | ||
206 | |||
207 | static Eina_Bool | ||
208 | _eio_dir_mkdir(Ecore_Thread *thread, Eio_Dir_Copy *order, | ||
209 | long long *step, long long count, | ||
210 | int length_source, int length_dest) | ||
211 | { | ||
212 | const char *dir; | ||
213 | Eina_List *l; | ||
214 | char target[PATH_MAX]; | ||
215 | |||
216 | /* create all directory */ | ||
217 | EINA_LIST_FOREACH(order->dirs, l, dir) | ||
218 | { | ||
219 | /* build target dir path */ | ||
220 | _eio_dir_target(order, target, dir, length_source, length_dest); | ||
221 | |||
222 | /* create the directory (we will apply the mode later) */ | ||
223 | if (mkdir(target, 0777) != 0) | ||
224 | { | ||
225 | eio_file_thread_error(&order->progress.common, thread); | ||
226 | return EINA_FALSE; | ||
227 | } | ||
228 | |||
229 | /* inform main thread */ | ||
230 | (*step)++; | ||
231 | eio_progress_send(thread, &order->progress, *step, count); | ||
232 | |||
233 | /* check for cancel request */ | ||
234 | if (ecore_thread_check(thread)) | ||
235 | return EINA_FALSE; | ||
236 | } | ||
237 | |||
238 | return EINA_TRUE; | ||
239 | } | ||
240 | |||
241 | static Eina_Bool | ||
242 | _eio_dir_link(Ecore_Thread *thread, Eio_Dir_Copy *order, | ||
243 | long long *step, long long count, | ||
244 | int length_source, int length_dest) | ||
245 | { | ||
246 | const char *ln; | ||
247 | Eina_List *l; | ||
248 | char oldpath[PATH_MAX]; | ||
249 | char target[PATH_MAX]; | ||
250 | char buffer[PATH_MAX]; | ||
251 | char *newpath; | ||
252 | |||
253 | /* Build once the base of the link target */ | ||
254 | memcpy(buffer, order->progress.dest, length_dest); | ||
255 | buffer[length_dest] = '/'; | ||
256 | |||
257 | /* recreate all links */ | ||
258 | EINA_LIST_FOREACH(order->links, l, ln) | ||
259 | { | ||
260 | ssize_t length; | ||
261 | |||
262 | /* build oldpath link */ | ||
263 | _eio_dir_target(order, oldpath, ln, length_source, length_dest); | ||
264 | |||
265 | /* read link target */ | ||
266 | length = readlink(ln, target, PATH_MAX); | ||
267 | if (length < 0) | ||
268 | goto on_error; | ||
269 | |||
270 | if (strncmp(target, order->progress.source, length_source) == 0) | ||
271 | { | ||
272 | /* The link is inside the zone to copy, so rename it */ | ||
273 | memcpy(buffer + length_dest + 1, target + length_source, length - length_source + 1); | ||
274 | newpath = target; | ||
275 | } | ||
276 | else | ||
277 | { | ||
278 | /* The link is outside the zone to copy */ | ||
279 | newpath = target; | ||
280 | } | ||
281 | |||
282 | /* create the link */ | ||
283 | if (symlink(newpath, oldpath) != 0) | ||
284 | goto on_error; | ||
285 | |||
286 | /* inform main thread */ | ||
287 | (*step)++; | ||
288 | eio_progress_send(thread, &order->progress, *step, count); | ||
289 | |||
290 | /* check for cancel request */ | ||
291 | if (ecore_thread_check(thread)) | ||
292 | return EINA_FALSE; | ||
293 | } | ||
294 | |||
295 | return EINA_TRUE; | ||
296 | |||
297 | on_error: | ||
298 | eio_file_thread_error(&order->progress.common, thread); | ||
299 | return EINA_FALSE; | ||
300 | } | ||
301 | |||
302 | static Eina_Bool | ||
303 | _eio_dir_chmod(Ecore_Thread *thread, Eio_Dir_Copy *order, | ||
304 | long long *step, long long count, | ||
305 | int length_source, int length_dest, | ||
306 | Eina_Bool rmdir_source) | ||
307 | { | ||
308 | const char *dir; | ||
309 | char target[PATH_MAX]; | ||
310 | struct stat buffer; | ||
311 | |||
312 | while(order->dirs) | ||
313 | { | ||
314 | /* destroy in reverse order so that we don't prevent change of lower dir */ | ||
315 | dir = eina_list_data_get(eina_list_last(order->dirs)); | ||
316 | order->dirs = eina_list_remove_list(order->dirs, eina_list_last(order->dirs)); | ||
317 | |||
318 | /* build target dir path */ | ||
319 | _eio_dir_target(order, target, dir, length_source, length_dest); | ||
320 | |||
321 | /* FIXME: in some case we already did a stat call, so would be nice to reuse previous result here */ | ||
322 | /* stat the original dir for mode info */ | ||
323 | if (stat(dir, &buffer) != 0) | ||
324 | goto on_error; | ||
325 | |||
326 | /* set the orginal mode to the newly created dir */ | ||
327 | if (chmod(target, buffer.st_mode) != 0) | ||
328 | goto on_error; | ||
329 | |||
330 | /* if required destroy original directory */ | ||
331 | if (rmdir_source) | ||
332 | { | ||
333 | if (rmdir(dir) != 0) | ||
334 | goto on_error; | ||
335 | } | ||
336 | |||
337 | /* inform main thread */ | ||
338 | (*step)++; | ||
339 | eio_progress_send(thread, &order->progress, *step, count); | ||
340 | |||
341 | /* check for cancel request */ | ||
342 | if (ecore_thread_check(thread)) | ||
343 | goto on_cancel; | ||
344 | |||
345 | eina_stringshare_del(dir); | ||
346 | } | ||
347 | |||
348 | return EINA_TRUE; | ||
349 | |||
350 | on_error: | ||
351 | eio_file_thread_error(&order->progress.common, thread); | ||
352 | on_cancel: | ||
353 | if (dir) eina_stringshare_del(dir); | ||
354 | return EINA_FALSE; | ||
355 | } | ||
356 | |||
357 | static void | ||
358 | _eio_dir_copy_heavy(void *data, Ecore_Thread *thread) | ||
359 | { | ||
360 | Eio_Dir_Copy *copy = data; | ||
361 | const char *file = NULL; | ||
362 | const char *dir; | ||
363 | const char *ln; | ||
364 | |||
365 | Eio_File_Progress file_copy; | ||
366 | char target[PATH_MAX]; | ||
367 | |||
368 | int length_source = 0; | ||
369 | int length_dest = 0; | ||
370 | long long count; | ||
371 | long long step; | ||
372 | |||
373 | /* list all the content that should be copied */ | ||
374 | if (!_eio_dir_recursiv_ls(thread, copy, copy->progress.source)) | ||
375 | return ; | ||
376 | |||
377 | /* init all structure needed to copy the file */ | ||
378 | if (!_eio_dir_init(thread, &step, &count, &length_source, &length_dest, copy, &file_copy)) | ||
379 | goto on_error; | ||
380 | |||
381 | /* suboperation is a file copy */ | ||
382 | file_copy.op = EIO_FILE_COPY; | ||
383 | |||
384 | /* create all directory */ | ||
385 | if (!_eio_dir_mkdir(thread, copy, &step, count, length_source, length_dest)) | ||
386 | goto on_error; | ||
387 | |||
388 | /* copy all files */ | ||
389 | EINA_LIST_FREE(copy->files, file) | ||
390 | { | ||
391 | /* build target file path */ | ||
392 | _eio_dir_target(copy, target, file, length_source, length_dest); | ||
393 | |||
394 | file_copy.source = file; | ||
395 | file_copy.dest = eina_stringshare_add(target); | ||
396 | |||
397 | /* copy the file */ | ||
398 | if (!eio_file_copy_do(thread, &file_copy)) | ||
399 | { | ||
400 | copy->progress.common.error = file_copy.common.error; | ||
401 | goto on_error; | ||
402 | } | ||
403 | |||
404 | /* notify main thread */ | ||
405 | step++; | ||
406 | eio_progress_send(thread, ©->progress, step, count); | ||
407 | |||
408 | if (ecore_thread_check(thread)) | ||
409 | goto on_error; | ||
410 | |||
411 | eina_stringshare_del(file_copy.dest); | ||
412 | eina_stringshare_del(file); | ||
413 | } | ||
414 | file_copy.dest = NULL; | ||
415 | file = NULL; | ||
416 | |||
417 | /* recreate link */ | ||
418 | if (!_eio_dir_link(thread, copy, &step, count, length_source, length_dest)) | ||
419 | goto on_error; | ||
420 | |||
421 | /* set directory right back */ | ||
422 | if (!_eio_dir_chmod(thread, copy, &step, count, length_source, length_dest, EINA_FALSE)) | ||
423 | goto on_error; | ||
424 | |||
425 | on_error: | ||
426 | /* cleanup the mess */ | ||
427 | if (file_copy.dest) eina_stringshare_del(file_copy.dest); | ||
428 | if (file) eina_stringshare_del(file); | ||
429 | |||
430 | EINA_LIST_FREE(copy->files, file) | ||
431 | eina_stringshare_del(file); | ||
432 | EINA_LIST_FREE(copy->dirs, dir) | ||
433 | eina_stringshare_del(dir); | ||
434 | EINA_LIST_FREE(copy->links, ln) | ||
435 | eina_stringshare_del(ln); | ||
436 | |||
437 | if (!ecore_thread_check(thread)) | ||
438 | eio_progress_send(thread, ©->progress, count, count); | ||
439 | |||
440 | return ; | ||
441 | } | ||
442 | |||
443 | static void | ||
444 | _eio_dir_copy_notify(void *data, Ecore_Thread *thread EINA_UNUSED, void *msg_data) | ||
445 | { | ||
446 | Eio_Dir_Copy *copy = data; | ||
447 | Eio_Progress *progress = msg_data; | ||
448 | |||
449 | eio_progress_cb(progress, ©->progress); | ||
450 | } | ||
451 | |||
452 | static void | ||
453 | _eio_dir_copy_free(Eio_Dir_Copy *copy) | ||
454 | { | ||
455 | eina_stringshare_del(copy->progress.source); | ||
456 | eina_stringshare_del(copy->progress.dest); | ||
457 | eio_file_free(©->progress.common); | ||
458 | } | ||
459 | |||
460 | static void | ||
461 | _eio_dir_copy_end(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
462 | { | ||
463 | Eio_Dir_Copy *copy = data; | ||
464 | |||
465 | copy->progress.common.done_cb((void*) copy->progress.common.data, ©->progress.common); | ||
466 | |||
467 | _eio_dir_copy_free(copy); | ||
468 | } | ||
469 | |||
470 | static void | ||
471 | _eio_dir_copy_error(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
472 | { | ||
473 | Eio_Dir_Copy *copy = data; | ||
474 | |||
475 | eio_file_error(©->progress.common); | ||
476 | |||
477 | _eio_dir_copy_free(copy); | ||
478 | } | ||
479 | |||
480 | static void | ||
481 | _eio_dir_move_heavy(void *data, Ecore_Thread *thread) | ||
482 | { | ||
483 | Eio_Dir_Copy *move = data; | ||
484 | const char *file = NULL; | ||
485 | const char *dir = NULL; | ||
486 | |||
487 | Eio_File_Progress file_move; | ||
488 | char target[PATH_MAX]; | ||
489 | |||
490 | int length_source; | ||
491 | int length_dest; | ||
492 | long long count; | ||
493 | long long step; | ||
494 | |||
495 | /* just try a rename, maybe we are lucky... */ | ||
496 | if (rename(move->progress.source, move->progress.dest) == 0) | ||
497 | { | ||
498 | /* we are really lucky */ | ||
499 | eio_progress_send(thread, &move->progress, 1, 1); | ||
500 | return ; | ||
501 | } | ||
502 | |||
503 | /* list all the content that should be moved */ | ||
504 | if (!_eio_dir_recursiv_ls(thread, move, move->progress.source)) | ||
505 | return ; | ||
506 | |||
507 | /* init all structure needed to move the file */ | ||
508 | if (!_eio_dir_init(thread, &step, &count, &length_source, &length_dest, move, &file_move)) | ||
509 | goto on_error; | ||
510 | |||
511 | /* sub operation is a file move */ | ||
512 | file_move.op = EIO_FILE_MOVE; | ||
513 | |||
514 | /* create all directory */ | ||
515 | if (!_eio_dir_mkdir(thread, move, &step, count, length_source, length_dest)) | ||
516 | goto on_error; | ||
517 | |||
518 | /* move file around */ | ||
519 | EINA_LIST_FREE(move->files, file) | ||
520 | { | ||
521 | /* build target file path */ | ||
522 | _eio_dir_target(move, target, file, length_source, length_dest); | ||
523 | |||
524 | file_move.source = file; | ||
525 | file_move.dest = eina_stringshare_add(target); | ||
526 | |||
527 | /* first try to rename */ | ||
528 | if (rename(file_move.source, file_move.dest) < 0) | ||
529 | { | ||
530 | if (errno != EXDEV) | ||
531 | { | ||
532 | eio_file_thread_error(&move->progress.common, thread); | ||
533 | goto on_error; | ||
534 | } | ||
535 | |||
536 | /* then try real copy */ | ||
537 | if (!eio_file_copy_do(thread, &file_move)) | ||
538 | { | ||
539 | move->progress.common.error = file_move.common.error; | ||
540 | goto on_error; | ||
541 | } | ||
542 | |||
543 | /* and unlink the original */ | ||
544 | if (unlink(file) != 0) | ||
545 | { | ||
546 | eio_file_thread_error(&move->progress.common, thread); | ||
547 | goto on_error; | ||
548 | } | ||
549 | } | ||
550 | |||
551 | step++; | ||
552 | eio_progress_send(thread, &move->progress, step, count); | ||
553 | |||
554 | if (ecore_thread_check(thread)) | ||
555 | goto on_error; | ||
556 | |||
557 | eina_stringshare_del(file_move.dest); | ||
558 | eina_stringshare_del(file); | ||
559 | } | ||
560 | file_move.dest = NULL; | ||
561 | file = NULL; | ||
562 | |||
563 | /* recreate link */ | ||
564 | if (!_eio_dir_link(thread, move, &step, count, length_source, length_dest)) | ||
565 | goto on_error; | ||
566 | |||
567 | /* set directory right back */ | ||
568 | if (!_eio_dir_chmod(thread, move, &step, count, length_source, length_dest, EINA_TRUE)) | ||
569 | goto on_error; | ||
570 | |||
571 | if (rmdir(move->progress.source) != 0) | ||
572 | goto on_error; | ||
573 | |||
574 | on_error: | ||
575 | /* cleanup the mess */ | ||
576 | if (file_move.dest) eina_stringshare_del(file_move.dest); | ||
577 | if (file) eina_stringshare_del(file); | ||
578 | |||
579 | EINA_LIST_FREE(move->files, file) | ||
580 | eina_stringshare_del(file); | ||
581 | EINA_LIST_FREE(move->dirs, dir) | ||
582 | eina_stringshare_del(dir); | ||
583 | |||
584 | if (!ecore_thread_check(thread)) | ||
585 | eio_progress_send(thread, &move->progress, count, count); | ||
586 | |||
587 | return; | ||
588 | } | ||
589 | |||
590 | static void | ||
591 | _eio_dir_rmrf_heavy(void *data, Ecore_Thread *thread) | ||
592 | { | ||
593 | Eio_Dir_Copy *rmrf = data; | ||
594 | const char *file = NULL; | ||
595 | const char *dir = NULL; | ||
596 | |||
597 | long long count; | ||
598 | long long step; | ||
599 | |||
600 | /* list all the content that should be moved */ | ||
601 | if (!_eio_dir_recursiv_ls(thread, rmrf, rmrf->progress.source)) | ||
602 | return ; | ||
603 | |||
604 | /* init counter */ | ||
605 | step = 0; | ||
606 | count = eina_list_count(rmrf->files) + eina_list_count(rmrf->dirs) + 1; | ||
607 | |||
608 | EINA_LIST_FREE(rmrf->files, file) | ||
609 | { | ||
610 | if (unlink(file) != 0) | ||
611 | { | ||
612 | eio_file_thread_error(&rmrf->progress.common, thread); | ||
613 | goto on_error; | ||
614 | } | ||
615 | |||
616 | eina_stringshare_replace(&rmrf->progress.dest, file); | ||
617 | |||
618 | step++; | ||
619 | eio_progress_send(thread, &rmrf->progress, step, count); | ||
620 | |||
621 | if (ecore_thread_check(thread)) | ||
622 | goto on_error; | ||
623 | |||
624 | eina_stringshare_del(file); | ||
625 | } | ||
626 | file = NULL; | ||
627 | |||
628 | /* reverse directory listing, so the leaf would be destroyed before | ||
629 | the root */ | ||
630 | rmrf->dirs = eina_list_reverse(rmrf->dirs); | ||
631 | |||
632 | EINA_LIST_FREE(rmrf->dirs, dir) | ||
633 | { | ||
634 | if (rmdir(dir) != 0) | ||
635 | { | ||
636 | eio_file_thread_error(&rmrf->progress.common, thread); | ||
637 | goto on_error; | ||
638 | } | ||
639 | |||
640 | eina_stringshare_replace(&rmrf->progress.dest, dir); | ||
641 | |||
642 | step++; | ||
643 | eio_progress_send(thread, &rmrf->progress, step, count); | ||
644 | |||
645 | if (ecore_thread_check(thread)) | ||
646 | goto on_error; | ||
647 | |||
648 | eina_stringshare_del(dir); | ||
649 | } | ||
650 | dir = NULL; | ||
651 | |||
652 | if (rmdir(rmrf->progress.source) != 0) | ||
653 | goto on_error; | ||
654 | step++; | ||
655 | |||
656 | on_error: | ||
657 | if (dir) eina_stringshare_del(dir); | ||
658 | if (file) eina_stringshare_del(file); | ||
659 | |||
660 | EINA_LIST_FREE(rmrf->dirs, dir) | ||
661 | eina_stringshare_del(dir); | ||
662 | EINA_LIST_FREE(rmrf->files, file) | ||
663 | eina_stringshare_del(file); | ||
664 | |||
665 | if (!ecore_thread_check(thread)) | ||
666 | eio_progress_send(thread, &rmrf->progress, count, count); | ||
667 | |||
668 | return; | ||
669 | } | ||
670 | |||
671 | static Eina_Bool | ||
672 | _eio_dir_stat_find_forward(Eio_File_Dir_Ls *async, | ||
673 | Eio_File *handler, | ||
674 | Eina_File_Direct_Info *info) | ||
675 | { | ||
676 | Eina_Bool filter = EINA_TRUE; | ||
677 | double current; | ||
678 | |||
679 | if (async->filter_cb) | ||
680 | { | ||
681 | filter = async->filter_cb((void*) async->ls.common.data, &async->ls.common, info); | ||
682 | } | ||
683 | |||
684 | if (filter) | ||
685 | { | ||
686 | Eio_File_Direct_Info *send_di; | ||
687 | |||
688 | send_di = eio_direct_info_malloc(); | ||
689 | if (!send_di) return EINA_FALSE; | ||
690 | |||
691 | memcpy(&send_di->info, info, sizeof (Eina_File_Direct_Info)); | ||
692 | send_di->associated = async->ls.common.worker.associated; | ||
693 | async->ls.common.worker.associated = NULL; | ||
694 | |||
695 | async->pack = eina_list_append(async->pack, send_di); | ||
696 | } | ||
697 | else if (async->ls.common.worker.associated) | ||
698 | { | ||
699 | eina_hash_free(async->ls.common.worker.associated); | ||
700 | async->ls.common.worker.associated = NULL; | ||
701 | } | ||
702 | |||
703 | current = ecore_time_get(); | ||
704 | if (current - async->start > EIO_PACKED_TIME) | ||
705 | { | ||
706 | async->start = current; | ||
707 | ecore_thread_feedback(handler->thread, async->pack); | ||
708 | async->pack = NULL; | ||
709 | } | ||
710 | |||
711 | return filter; | ||
712 | } | ||
713 | |||
714 | static void | ||
715 | _eio_dir_stat_find_heavy(void *data, Ecore_Thread *thread) | ||
716 | { | ||
717 | Eio_File_Dir_Ls *async = data; | ||
718 | |||
719 | async->ls.common.thread = thread; | ||
720 | async->pack = NULL; | ||
721 | async->start = ecore_time_get(); | ||
722 | |||
723 | _eio_file_recursiv_ls(thread, &async->ls.common, | ||
724 | (Eio_Filter_Direct_Cb) _eio_dir_stat_find_forward, | ||
725 | eina_file_stat_ls, | ||
726 | async, async->ls.directory); | ||
727 | |||
728 | if (async->pack) ecore_thread_feedback(thread, async->pack); | ||
729 | async->pack = NULL; | ||
730 | } | ||
731 | |||
732 | static void | ||
733 | _eio_dir_direct_find_heavy(void *data, Ecore_Thread *thread) | ||
734 | { | ||
735 | Eio_File_Dir_Ls *async = data; | ||
736 | |||
737 | async->ls.common.thread = thread; | ||
738 | async->pack = NULL; | ||
739 | async->start = ecore_time_get(); | ||
740 | |||
741 | _eio_file_recursiv_ls(thread, &async->ls.common, | ||
742 | (Eio_Filter_Direct_Cb) _eio_dir_stat_find_forward, | ||
743 | eina_file_direct_ls, | ||
744 | async, async->ls.directory); | ||
745 | |||
746 | if (async->pack) ecore_thread_feedback(thread, async->pack); | ||
747 | async->pack = NULL; | ||
748 | } | ||
749 | |||
750 | static void | ||
751 | _eio_dir_stat_find_notify(void *data, Ecore_Thread *thread EINA_UNUSED, void *msg_data) | ||
752 | { | ||
753 | Eio_File_Dir_Ls *async = data; | ||
754 | Eina_List *pack = msg_data; | ||
755 | Eio_File_Direct_Info *info; | ||
756 | |||
757 | EINA_LIST_FREE(pack, info) | ||
758 | { | ||
759 | async->ls.common.main.associated = info->associated; | ||
760 | |||
761 | async->main_cb((void*) async->ls.common.data, &async->ls.common, &info->info); | ||
762 | |||
763 | if (async->ls.common.main.associated) | ||
764 | { | ||
765 | eina_hash_free(async->ls.common.main.associated); | ||
766 | async->ls.common.main.associated = NULL; | ||
767 | } | ||
768 | |||
769 | eio_direct_info_free(info); | ||
770 | } | ||
771 | } | ||
772 | |||
773 | static void | ||
774 | _eio_dir_stat_done(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
775 | { | ||
776 | Eio_File_Ls *async = data; | ||
777 | |||
778 | async->common.done_cb((void*) async->common.data, &async->common); | ||
779 | |||
780 | eio_async_free(async); | ||
781 | } | ||
782 | |||
783 | static void | ||
784 | _eio_dir_stat_error(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
785 | { | ||
786 | Eio_File_Ls *async = data; | ||
787 | |||
788 | eio_file_error(&async->common); | ||
789 | |||
790 | eio_async_free(async); | ||
791 | } | ||
792 | |||
793 | /** | ||
794 | * @endcond | ||
795 | */ | ||
796 | |||
797 | /*============================================================================* | ||
798 | * Global * | ||
799 | *============================================================================*/ | ||
800 | |||
801 | |||
802 | /*============================================================================* | ||
803 | * API * | ||
804 | *============================================================================*/ | ||
805 | |||
806 | |||
807 | EAPI Eio_File * | ||
808 | eio_dir_copy(const char *source, | ||
809 | const char *dest, | ||
810 | Eio_Filter_Direct_Cb filter_cb, | ||
811 | Eio_Progress_Cb progress_cb, | ||
812 | Eio_Done_Cb done_cb, | ||
813 | Eio_Error_Cb error_cb, | ||
814 | const void *data) | ||
815 | { | ||
816 | Eio_Dir_Copy *copy; | ||
817 | |||
818 | EINA_SAFETY_ON_NULL_RETURN_VAL(source, NULL); | ||
819 | EINA_SAFETY_ON_NULL_RETURN_VAL(dest, NULL); | ||
820 | EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL); | ||
821 | EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL); | ||
822 | |||
823 | copy = malloc(sizeof(Eio_Dir_Copy)); | ||
824 | EINA_SAFETY_ON_NULL_RETURN_VAL(copy, NULL); | ||
825 | |||
826 | copy->progress.op = EIO_DIR_COPY; | ||
827 | copy->progress.progress_cb = progress_cb; | ||
828 | copy->progress.source = eina_stringshare_add(source); | ||
829 | copy->progress.dest = eina_stringshare_add(dest); | ||
830 | copy->filter_cb = filter_cb; | ||
831 | copy->files = NULL; | ||
832 | copy->dirs = NULL; | ||
833 | copy->links = NULL; | ||
834 | |||
835 | if (!eio_long_file_set(©->progress.common, | ||
836 | done_cb, | ||
837 | error_cb, | ||
838 | data, | ||
839 | _eio_dir_copy_heavy, | ||
840 | _eio_dir_copy_notify, | ||
841 | _eio_dir_copy_end, | ||
842 | _eio_dir_copy_error)) | ||
843 | return NULL; | ||
844 | |||
845 | return ©->progress.common; | ||
846 | } | ||
847 | |||
848 | EAPI Eio_File * | ||
849 | eio_dir_move(const char *source, | ||
850 | const char *dest, | ||
851 | Eio_Filter_Direct_Cb filter_cb, | ||
852 | Eio_Progress_Cb progress_cb, | ||
853 | Eio_Done_Cb done_cb, | ||
854 | Eio_Error_Cb error_cb, | ||
855 | const void *data) | ||
856 | { | ||
857 | Eio_Dir_Copy *move; | ||
858 | |||
859 | EINA_SAFETY_ON_NULL_RETURN_VAL(source, NULL); | ||
860 | EINA_SAFETY_ON_NULL_RETURN_VAL(dest, NULL); | ||
861 | EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL); | ||
862 | EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL); | ||
863 | |||
864 | move = malloc(sizeof(Eio_Dir_Copy)); | ||
865 | EINA_SAFETY_ON_NULL_RETURN_VAL(move, NULL); | ||
866 | |||
867 | move->progress.op = EIO_DIR_MOVE; | ||
868 | move->progress.progress_cb = progress_cb; | ||
869 | move->progress.source = eina_stringshare_add(source); | ||
870 | move->progress.dest = eina_stringshare_add(dest); | ||
871 | move->filter_cb = filter_cb; | ||
872 | move->files = NULL; | ||
873 | move->dirs = NULL; | ||
874 | move->links = NULL; | ||
875 | |||
876 | if (!eio_long_file_set(&move->progress.common, | ||
877 | done_cb, | ||
878 | error_cb, | ||
879 | data, | ||
880 | _eio_dir_move_heavy, | ||
881 | _eio_dir_copy_notify, | ||
882 | _eio_dir_copy_end, | ||
883 | _eio_dir_copy_error)) | ||
884 | return NULL; | ||
885 | |||
886 | return &move->progress.common; | ||
887 | } | ||
888 | |||
889 | EAPI Eio_File * | ||
890 | eio_dir_unlink(const char *path, | ||
891 | Eio_Filter_Direct_Cb filter_cb, | ||
892 | Eio_Progress_Cb progress_cb, | ||
893 | Eio_Done_Cb done_cb, | ||
894 | Eio_Error_Cb error_cb, | ||
895 | const void *data) | ||
896 | { | ||
897 | Eio_Dir_Copy *rmrf; | ||
898 | |||
899 | EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL); | ||
900 | EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL); | ||
901 | EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL); | ||
902 | |||
903 | rmrf = malloc(sizeof(Eio_Dir_Copy)); | ||
904 | EINA_SAFETY_ON_NULL_RETURN_VAL(rmrf, NULL); | ||
905 | |||
906 | rmrf->progress.op = EIO_UNLINK; | ||
907 | rmrf->progress.progress_cb = progress_cb; | ||
908 | rmrf->progress.source = eina_stringshare_add(path); | ||
909 | rmrf->progress.dest = NULL; | ||
910 | rmrf->filter_cb = filter_cb; | ||
911 | rmrf->files = NULL; | ||
912 | rmrf->dirs = NULL; | ||
913 | rmrf->links = NULL; | ||
914 | |||
915 | if (!eio_long_file_set(&rmrf->progress.common, | ||
916 | done_cb, | ||
917 | error_cb, | ||
918 | data, | ||
919 | _eio_dir_rmrf_heavy, | ||
920 | _eio_dir_copy_notify, | ||
921 | _eio_dir_copy_end, | ||
922 | _eio_dir_copy_error)) | ||
923 | return NULL; | ||
924 | |||
925 | return &rmrf->progress.common; | ||
926 | } | ||
927 | |||
928 | EAPI Eio_File * | ||
929 | eio_dir_stat_ls(const char *dir, | ||
930 | Eio_Filter_Direct_Cb filter_cb, | ||
931 | Eio_Main_Direct_Cb main_cb, | ||
932 | Eio_Done_Cb done_cb, | ||
933 | Eio_Error_Cb error_cb, | ||
934 | const void *data) | ||
935 | { | ||
936 | Eio_File_Dir_Ls *async; | ||
937 | |||
938 | EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL); | ||
939 | EINA_SAFETY_ON_NULL_RETURN_VAL(main_cb, NULL); | ||
940 | EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL); | ||
941 | EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL); | ||
942 | |||
943 | async = malloc(sizeof(Eio_File_Dir_Ls)); | ||
944 | EINA_SAFETY_ON_NULL_RETURN_VAL(async, NULL); | ||
945 | |||
946 | /* Eio_Filter_Direct_Cb must be casted to Eio_Filter_Dir_Cb here | ||
947 | * because we keep the Eio_File_Dir_Ls pointing to that variant | ||
948 | * where info can be modified, but in our case it's already doing | ||
949 | * stat() then it shouldn't be needed! | ||
950 | */ | ||
951 | async->filter_cb = (Eio_Filter_Dir_Cb)filter_cb; | ||
952 | async->main_cb = main_cb; | ||
953 | async->ls.directory = eina_stringshare_add(dir); | ||
954 | |||
955 | if (!eio_long_file_set(&async->ls.common, | ||
956 | done_cb, | ||
957 | error_cb, | ||
958 | data, | ||
959 | _eio_dir_stat_find_heavy, | ||
960 | _eio_dir_stat_find_notify, | ||
961 | _eio_dir_stat_done, | ||
962 | _eio_dir_stat_error)) | ||
963 | return NULL; | ||
964 | |||
965 | return &async->ls.common; | ||
966 | } | ||
967 | |||
968 | EAPI Eio_File * | ||
969 | eio_dir_direct_ls(const char *dir, | ||
970 | Eio_Filter_Dir_Cb filter_cb, | ||
971 | Eio_Main_Direct_Cb main_cb, | ||
972 | Eio_Done_Cb done_cb, | ||
973 | Eio_Error_Cb error_cb, | ||
974 | const void *data) | ||
975 | { | ||
976 | Eio_File_Dir_Ls *async; | ||
977 | |||
978 | EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL); | ||
979 | EINA_SAFETY_ON_NULL_RETURN_VAL(main_cb, NULL); | ||
980 | EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL); | ||
981 | EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL); | ||
982 | |||
983 | async = malloc(sizeof(Eio_File_Dir_Ls)); | ||
984 | EINA_SAFETY_ON_NULL_RETURN_VAL(async, NULL); | ||
985 | |||
986 | async->filter_cb = filter_cb; | ||
987 | async->main_cb = main_cb; | ||
988 | async->ls.directory = eina_stringshare_add(dir); | ||
989 | |||
990 | if (!eio_long_file_set(&async->ls.common, | ||
991 | done_cb, | ||
992 | error_cb, | ||
993 | data, | ||
994 | _eio_dir_direct_find_heavy, | ||
995 | _eio_dir_stat_find_notify, | ||
996 | _eio_dir_stat_done, | ||
997 | _eio_dir_stat_error)) | ||
998 | return NULL; | ||
999 | |||
1000 | return &async->ls.common; | ||
1001 | } | ||
diff --git a/src/lib/eio/eio_eet.c b/src/lib/eio/eio_eet.c new file mode 100644 index 0000000000..c25cc4a035 --- /dev/null +++ b/src/lib/eio/eio_eet.c | |||
@@ -0,0 +1,640 @@ | |||
1 | /* EIO - EFL data type library | ||
2 | * Copyright (C) 2010 Enlightenment Developers: | ||
3 | * Cedric Bail <cedric.bail@free.fr> | ||
4 | * Vincent "caro" Torri <vtorri at univ-evry dot fr> | ||
5 | * Stephen "okra" Houston <UnixTitan@gmail.com> | ||
6 | * | ||
7 | * This library is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This library is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library; | ||
19 | * if not, see <http://www.gnu.org/licenses/>. | ||
20 | */ | ||
21 | |||
22 | #include "eio_private.h" | ||
23 | #include "Eio.h" | ||
24 | |||
25 | /*============================================================================* | ||
26 | * Local * | ||
27 | *============================================================================*/ | ||
28 | |||
29 | /** | ||
30 | * @cond LOCAL | ||
31 | */ | ||
32 | |||
33 | static void | ||
34 | _eio_eet_open_job(void *data, Ecore_Thread *thread) | ||
35 | { | ||
36 | Eio_Eet_Open *eet = data; | ||
37 | |||
38 | eet->result = eet_open(eet->filename, eet->mode); | ||
39 | if (!eet->result) eio_file_thread_error(&eet->common, thread); | ||
40 | } | ||
41 | |||
42 | static void | ||
43 | _eio_eet_open_free(Eio_Eet_Open *eet) | ||
44 | { | ||
45 | if (eet->filename) eina_stringshare_del(eet->filename); | ||
46 | free(eet); | ||
47 | } | ||
48 | |||
49 | static void | ||
50 | _eio_eet_open_end(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
51 | { | ||
52 | Eio_Eet_Open *eet = data; | ||
53 | |||
54 | eet->eet_cb((void*) eet->common.data, &eet->common, eet->result); | ||
55 | _eio_eet_open_free(eet); | ||
56 | } | ||
57 | |||
58 | static void | ||
59 | _eio_eet_open_cancel(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
60 | { | ||
61 | Eio_Eet_Open *eet = data; | ||
62 | |||
63 | eio_file_error(&eet->common); | ||
64 | _eio_eet_open_free(eet); | ||
65 | } | ||
66 | |||
67 | static void | ||
68 | _eio_eet_close_job(void *data, Ecore_Thread *thread) | ||
69 | { | ||
70 | Eio_Eet_Simple *eet = data; | ||
71 | |||
72 | eet->error = eet_close(eet->ef); | ||
73 | if (eet->error != EET_ERROR_NONE) eio_file_thread_error(&eet->common, thread); | ||
74 | } | ||
75 | |||
76 | static void | ||
77 | _eio_eet_sync_job(void *data, Ecore_Thread *thread) | ||
78 | { | ||
79 | Eio_Eet_Simple *eet = data; | ||
80 | |||
81 | eet->error = eet_sync(eet->ef); | ||
82 | if (eet->error != EET_ERROR_NONE) eio_file_thread_error(&eet->common, thread); | ||
83 | } | ||
84 | |||
85 | static void | ||
86 | _eio_eet_simple_end(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
87 | { | ||
88 | Eio_Eet_Simple *eet = data; | ||
89 | |||
90 | eet->common.done_cb((void*) eet->common.data, &eet->common); | ||
91 | free(eet); | ||
92 | } | ||
93 | |||
94 | static void | ||
95 | _eio_eet_simple_cancel(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
96 | { | ||
97 | Eio_Eet_Simple *eet = data; | ||
98 | |||
99 | eet->error_cb((void*) eet->common.data, &eet->common, eet->error); | ||
100 | free(eet); | ||
101 | } | ||
102 | |||
103 | static void | ||
104 | _eio_eet_data_write_cipher_job(void *data, Ecore_Thread *thread) | ||
105 | { | ||
106 | Eio_Eet_Write *ew = data; | ||
107 | |||
108 | ew->result = eet_data_write_cipher(ew->ef, ew->edd, | ||
109 | ew->name, ew->cipher_key, | ||
110 | ew->write_data, | ||
111 | ew->compress); | ||
112 | if (ew->result == 0) eio_file_thread_error(&ew->common, thread); | ||
113 | } | ||
114 | |||
115 | static void | ||
116 | _eio_eet_write_cipher_free(Eio_Eet_Write *ew) | ||
117 | { | ||
118 | eina_stringshare_del(ew->name); | ||
119 | eina_stringshare_del(ew->cipher_key); | ||
120 | free(ew); | ||
121 | } | ||
122 | |||
123 | static void | ||
124 | _eio_eet_data_write_cipher_end(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
125 | { | ||
126 | Eio_Eet_Write *ew = data; | ||
127 | |||
128 | ew->done_cb((void*) ew->common.data, &ew->common, ew->result); | ||
129 | _eio_eet_write_cipher_free(ew); | ||
130 | } | ||
131 | |||
132 | static void | ||
133 | _eio_eet_data_write_cipher_cancel(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
134 | { | ||
135 | Eio_Eet_Write *ew = data; | ||
136 | |||
137 | eio_file_error(&ew->common); | ||
138 | _eio_eet_write_cipher_free(ew); | ||
139 | } | ||
140 | |||
141 | static void | ||
142 | _eio_eet_image_write_job(void *data, Ecore_Thread *thread) | ||
143 | { | ||
144 | Eio_Eet_Image_Write *eiw = data; | ||
145 | |||
146 | eiw->result = eet_data_image_write_cipher(eiw->ef, eiw->name, eiw->cipher_key, | ||
147 | eiw->write_data, | ||
148 | eiw->w, | ||
149 | eiw->h, | ||
150 | eiw->alpha, | ||
151 | eiw->compress, | ||
152 | eiw->quality, | ||
153 | eiw->lossy); | ||
154 | if (!eiw->result) eio_file_thread_error(&eiw->common, thread); | ||
155 | } | ||
156 | |||
157 | static void | ||
158 | _eio_eet_image_write_free(Eio_Eet_Image_Write *eiw) | ||
159 | { | ||
160 | eina_stringshare_del(eiw->name); | ||
161 | eina_stringshare_del(eiw->cipher_key); | ||
162 | free(eiw); | ||
163 | } | ||
164 | |||
165 | static void | ||
166 | _eio_eet_image_write_end(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
167 | { | ||
168 | Eio_Eet_Image_Write *eiw = data; | ||
169 | |||
170 | eiw->done_cb((void*) eiw->common.data, &eiw->common, eiw->result); | ||
171 | _eio_eet_image_write_free(eiw); | ||
172 | } | ||
173 | |||
174 | static void | ||
175 | _eio_eet_image_write_cancel(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
176 | { | ||
177 | Eio_Eet_Image_Write *eiw = data; | ||
178 | |||
179 | eio_file_error(&eiw->common); | ||
180 | _eio_eet_image_write_free(eiw); | ||
181 | } | ||
182 | |||
183 | static void | ||
184 | _eio_eet_write_job(void *data, Ecore_Thread *thread) | ||
185 | { | ||
186 | Eio_Eet_Write *ew = data; | ||
187 | |||
188 | ew->result = eet_write_cipher(ew->ef, | ||
189 | ew->name, ew->write_data, | ||
190 | ew->size, ew->compress, | ||
191 | ew->cipher_key); | ||
192 | if (!ew->result) eio_file_thread_error(&ew->common, thread); | ||
193 | } | ||
194 | |||
195 | static void | ||
196 | _eio_eet_write_end(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
197 | { | ||
198 | Eio_Eet_Write *ew = data; | ||
199 | |||
200 | ew->done_cb((void*) ew->common.data, &ew->common, ew->result); | ||
201 | _eio_eet_write_cipher_free(ew); | ||
202 | } | ||
203 | |||
204 | static void | ||
205 | _eio_eet_write_cancel(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
206 | { | ||
207 | Eio_Eet_Write *ew = data; | ||
208 | |||
209 | eio_file_error(&ew->common); | ||
210 | _eio_eet_write_cipher_free(ew); | ||
211 | } | ||
212 | |||
213 | static void | ||
214 | _eio_eet_data_read_cipher_job(void *data, Ecore_Thread *thread) | ||
215 | { | ||
216 | Eio_Eet_Read *er = data; | ||
217 | |||
218 | er->result = eet_data_read_cipher(er->ef, er->edd, | ||
219 | er->name, er->cipher_key); | ||
220 | if (!er->result) eio_file_thread_error(&er->common, thread); | ||
221 | } | ||
222 | |||
223 | static void | ||
224 | _eio_eet_read_free(Eio_Eet_Read *er) | ||
225 | { | ||
226 | eina_stringshare_del(er->name); | ||
227 | eina_stringshare_del(er->cipher_key); | ||
228 | free(er); | ||
229 | } | ||
230 | |||
231 | static void | ||
232 | _eio_eet_data_read_cipher_end(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
233 | { | ||
234 | Eio_Eet_Read *er = data; | ||
235 | |||
236 | er->done_cb.eread((void*) er->common.data, &er->common, er->result); | ||
237 | _eio_eet_read_free(er); | ||
238 | } | ||
239 | |||
240 | static void | ||
241 | _eio_eet_data_read_cipher_cancel(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
242 | { | ||
243 | Eio_Eet_Read *er = data; | ||
244 | |||
245 | eio_file_error(&er->common); | ||
246 | _eio_eet_read_free(er); | ||
247 | } | ||
248 | |||
249 | static void | ||
250 | _eio_eet_read_direct_job(void *data, Ecore_Thread *thread) | ||
251 | { | ||
252 | Eio_Eet_Read *er = data; | ||
253 | |||
254 | er->result = (void*) eet_read_direct(er->ef, er->name, &er->size); | ||
255 | if (!er->result) eio_file_thread_error(&er->common, thread); | ||
256 | } | ||
257 | |||
258 | static void | ||
259 | _eio_eet_read_direct_end(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
260 | { | ||
261 | Eio_Eet_Read *er = data; | ||
262 | |||
263 | er->done_cb.data((void*) er->common.data, &er->common, | ||
264 | er->result, er->size); | ||
265 | _eio_eet_read_free(er); | ||
266 | } | ||
267 | |||
268 | static void | ||
269 | _eio_eet_read_cancel(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
270 | { | ||
271 | Eio_Eet_Read *er = data; | ||
272 | |||
273 | eio_file_error(&er->common); | ||
274 | _eio_eet_read_free(er); | ||
275 | } | ||
276 | |||
277 | static void | ||
278 | _eio_eet_read_cipher_job(void *data, Ecore_Thread *thread) | ||
279 | { | ||
280 | Eio_Eet_Read *er = data; | ||
281 | |||
282 | er->result = (void*) eet_read_cipher(er->ef, er->name, | ||
283 | &er->size, er->cipher_key); | ||
284 | if (!er->result) eio_file_thread_error(&er->common, thread); | ||
285 | } | ||
286 | |||
287 | static void | ||
288 | _eio_eet_read_cipher_end(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
289 | { | ||
290 | Eio_Eet_Read *er = data; | ||
291 | |||
292 | er->done_cb.read((void*) er->common.data, &er->common, | ||
293 | er->result, er->size); | ||
294 | _eio_eet_read_free(er); | ||
295 | } | ||
296 | |||
297 | /** | ||
298 | * @endcond | ||
299 | */ | ||
300 | |||
301 | /*============================================================================* | ||
302 | * Global * | ||
303 | *============================================================================*/ | ||
304 | |||
305 | |||
306 | /*============================================================================* | ||
307 | * API * | ||
308 | *============================================================================*/ | ||
309 | |||
310 | EAPI Eio_File * | ||
311 | eio_eet_open(const char *filename, | ||
312 | Eet_File_Mode mode, | ||
313 | Eio_Eet_Open_Cb eet_cb, | ||
314 | Eio_Error_Cb error_cb, | ||
315 | const void *data) | ||
316 | { | ||
317 | Eio_Eet_Open *eet; | ||
318 | |||
319 | EINA_SAFETY_ON_NULL_RETURN_VAL(filename, NULL); | ||
320 | EINA_SAFETY_ON_NULL_RETURN_VAL(eet_cb, NULL); | ||
321 | EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL); | ||
322 | |||
323 | eet = malloc(sizeof (Eio_Eet_Open)); | ||
324 | EINA_SAFETY_ON_NULL_RETURN_VAL(eet, NULL); | ||
325 | |||
326 | eet->eet_cb = eet_cb; | ||
327 | eet->filename = eina_stringshare_add(filename); | ||
328 | eet->mode = mode; | ||
329 | eet->result = NULL; | ||
330 | |||
331 | if (!eio_file_set(&eet->common, | ||
332 | NULL, | ||
333 | error_cb, | ||
334 | data, | ||
335 | _eio_eet_open_job, | ||
336 | _eio_eet_open_end, | ||
337 | _eio_eet_open_cancel)) | ||
338 | return NULL; | ||
339 | return &eet->common; | ||
340 | } | ||
341 | |||
342 | EAPI Eio_File * | ||
343 | eio_eet_close(Eet_File *ef, | ||
344 | Eio_Done_Cb done_cb, | ||
345 | Eio_Eet_Error_Cb error_cb, | ||
346 | const void *data) | ||
347 | { | ||
348 | Eio_Eet_Simple *eet; | ||
349 | |||
350 | EINA_SAFETY_ON_NULL_RETURN_VAL(ef, NULL); | ||
351 | EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL); | ||
352 | EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL); | ||
353 | |||
354 | eet = malloc(sizeof (Eio_Eet_Simple)); | ||
355 | EINA_SAFETY_ON_NULL_RETURN_VAL(eet, NULL); | ||
356 | |||
357 | eet->ef = ef; | ||
358 | eet->error_cb = error_cb; | ||
359 | eet->error = EET_ERROR_NONE; | ||
360 | |||
361 | if (!eio_file_set(&eet->common, | ||
362 | done_cb, | ||
363 | NULL, | ||
364 | data, | ||
365 | _eio_eet_close_job, | ||
366 | _eio_eet_simple_end, | ||
367 | _eio_eet_simple_cancel)) | ||
368 | return NULL; | ||
369 | return &eet->common; | ||
370 | } | ||
371 | |||
372 | EAPI Eio_File * | ||
373 | eio_eet_flush(Eet_File *ef, | ||
374 | Eio_Done_Cb done_cb, | ||
375 | Eio_Eet_Error_Cb error_cb, | ||
376 | const void *data) | ||
377 | { | ||
378 | Eio_Eet_Simple *eet; | ||
379 | |||
380 | EINA_SAFETY_ON_NULL_RETURN_VAL(ef, NULL); | ||
381 | EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL); | ||
382 | EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL); | ||
383 | |||
384 | eet = malloc(sizeof (Eio_Eet_Simple)); | ||
385 | EINA_SAFETY_ON_NULL_RETURN_VAL(eet, NULL); | ||
386 | |||
387 | eet->ef = ef; | ||
388 | eet->error_cb = error_cb; | ||
389 | eet->error = EET_ERROR_NONE; | ||
390 | |||
391 | if (!eio_file_set(&eet->common, | ||
392 | done_cb, | ||
393 | NULL, | ||
394 | data, | ||
395 | _eio_eet_sync_job, | ||
396 | _eio_eet_simple_end, | ||
397 | _eio_eet_simple_cancel)) | ||
398 | return NULL; | ||
399 | return &eet->common; | ||
400 | } | ||
401 | |||
402 | EAPI Eio_File * | ||
403 | eio_eet_data_write_cipher(Eet_File *ef, | ||
404 | Eet_Data_Descriptor *edd, | ||
405 | const char *name, | ||
406 | const char *cipher_key, | ||
407 | void *write_data, | ||
408 | int compress, | ||
409 | Eio_Done_Int_Cb done_cb, | ||
410 | Eio_Error_Cb error_cb, | ||
411 | const void *user_data) | ||
412 | { | ||
413 | Eio_Eet_Write *ew; | ||
414 | |||
415 | EINA_SAFETY_ON_NULL_RETURN_VAL(ef, NULL); | ||
416 | EINA_SAFETY_ON_NULL_RETURN_VAL(edd, NULL); | ||
417 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL); | ||
418 | EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL); | ||
419 | EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL); | ||
420 | |||
421 | ew = malloc(sizeof (Eio_Eet_Write)); | ||
422 | EINA_SAFETY_ON_NULL_RETURN_VAL(ew, NULL); | ||
423 | |||
424 | ew->ef = ef; | ||
425 | ew->edd = edd; | ||
426 | ew->name = eina_stringshare_add(name); | ||
427 | ew->cipher_key = eina_stringshare_add(cipher_key); | ||
428 | ew->write_data = write_data; | ||
429 | ew->compress = compress; | ||
430 | ew->done_cb = done_cb; | ||
431 | ew->result = 0; | ||
432 | |||
433 | if (!eio_file_set(&ew->common, | ||
434 | NULL, | ||
435 | error_cb, | ||
436 | user_data, | ||
437 | _eio_eet_data_write_cipher_job, | ||
438 | _eio_eet_data_write_cipher_end, | ||
439 | _eio_eet_data_write_cipher_cancel)) | ||
440 | return NULL; | ||
441 | return &ew->common; | ||
442 | } | ||
443 | |||
444 | EAPI Eio_File * | ||
445 | eio_eet_data_read_cipher(Eet_File *ef, | ||
446 | Eet_Data_Descriptor *edd, | ||
447 | const char *name, | ||
448 | const char *cipher_key, | ||
449 | Eio_Done_ERead_Cb done_cb, | ||
450 | Eio_Error_Cb error_cb, | ||
451 | const void *data) | ||
452 | { | ||
453 | Eio_Eet_Read *er; | ||
454 | |||
455 | EINA_SAFETY_ON_NULL_RETURN_VAL(ef, NULL); | ||
456 | EINA_SAFETY_ON_NULL_RETURN_VAL(edd, NULL); | ||
457 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL); | ||
458 | EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL); | ||
459 | EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL); | ||
460 | |||
461 | er = malloc(sizeof (Eio_Eet_Read)); | ||
462 | EINA_SAFETY_ON_NULL_RETURN_VAL(er, NULL); | ||
463 | |||
464 | er->ef = ef; | ||
465 | er->edd = edd; | ||
466 | er->name = eina_stringshare_add(name); | ||
467 | er->cipher_key = eina_stringshare_add(cipher_key); | ||
468 | er->done_cb.eread = done_cb; | ||
469 | |||
470 | if (!eio_file_set(&er->common, | ||
471 | NULL, | ||
472 | error_cb, | ||
473 | data, | ||
474 | _eio_eet_data_read_cipher_job, | ||
475 | _eio_eet_data_read_cipher_end, | ||
476 | _eio_eet_data_read_cipher_cancel)) | ||
477 | return NULL; | ||
478 | |||
479 | return &er->common; | ||
480 | } | ||
481 | |||
482 | EAPI Eio_File * | ||
483 | eio_eet_data_image_write_cipher(Eet_File *ef, | ||
484 | const char *name, | ||
485 | const char *cipher_key, | ||
486 | void *write_data, | ||
487 | unsigned int w, | ||
488 | unsigned int h, | ||
489 | int alpha, | ||
490 | int compress, | ||
491 | int quality, | ||
492 | int lossy, | ||
493 | Eio_Done_Int_Cb done_cb, | ||
494 | Eio_Error_Cb error_cb, | ||
495 | const void *user_data) | ||
496 | { | ||
497 | Eio_Eet_Image_Write *eiw; | ||
498 | |||
499 | EINA_SAFETY_ON_NULL_RETURN_VAL(ef, NULL); | ||
500 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL); | ||
501 | EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL); | ||
502 | EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL); | ||
503 | |||
504 | eiw = malloc(sizeof (Eio_Eet_Image_Write)); | ||
505 | EINA_SAFETY_ON_NULL_RETURN_VAL(eiw, NULL); | ||
506 | |||
507 | eiw->ef = ef; | ||
508 | eiw->name = eina_stringshare_add(name); | ||
509 | eiw->cipher_key = eina_stringshare_add(cipher_key); | ||
510 | eiw->write_data = write_data; | ||
511 | eiw->w = w; | ||
512 | eiw->h = h; | ||
513 | eiw->alpha = alpha; | ||
514 | eiw->compress = compress; | ||
515 | eiw->quality = quality; | ||
516 | eiw->lossy = lossy; | ||
517 | eiw->done_cb = done_cb; | ||
518 | eiw->result = 0; | ||
519 | |||
520 | if (!eio_file_set(&eiw->common, | ||
521 | NULL, | ||
522 | error_cb, | ||
523 | user_data, | ||
524 | _eio_eet_image_write_job, | ||
525 | _eio_eet_image_write_end, | ||
526 | _eio_eet_image_write_cancel)) | ||
527 | return NULL; | ||
528 | return &eiw->common; | ||
529 | } | ||
530 | |||
531 | EAPI Eio_File * | ||
532 | eio_eet_read_direct(Eet_File *ef, | ||
533 | const char *name, | ||
534 | Eio_Done_Data_Cb done_cb, | ||
535 | Eio_Error_Cb error_cb, | ||
536 | const void *data) | ||
537 | { | ||
538 | Eio_Eet_Read *er; | ||
539 | |||
540 | EINA_SAFETY_ON_NULL_RETURN_VAL(ef, NULL); | ||
541 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL); | ||
542 | EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL); | ||
543 | EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL); | ||
544 | |||
545 | er = malloc(sizeof (Eio_Eet_Read)); | ||
546 | EINA_SAFETY_ON_NULL_RETURN_VAL(er, NULL); | ||
547 | |||
548 | er->ef = ef; | ||
549 | er->name = eina_stringshare_add(name); | ||
550 | er->cipher_key = NULL; | ||
551 | er->done_cb.data = done_cb; | ||
552 | er->result = NULL; | ||
553 | |||
554 | if (!eio_file_set(&er->common, | ||
555 | NULL, | ||
556 | error_cb, | ||
557 | data, | ||
558 | _eio_eet_read_direct_job, | ||
559 | _eio_eet_read_direct_end, | ||
560 | _eio_eet_read_cancel)) | ||
561 | return NULL; | ||
562 | |||
563 | return &er->common; | ||
564 | } | ||
565 | |||
566 | EAPI Eio_File * | ||
567 | eio_eet_read_cipher(Eet_File *ef, | ||
568 | const char *name, | ||
569 | const char *cipher_key, | ||
570 | Eio_Done_Read_Cb done_cb, | ||
571 | Eio_Error_Cb error_cb, | ||
572 | const void *data) | ||
573 | { | ||
574 | Eio_Eet_Read *er; | ||
575 | |||
576 | EINA_SAFETY_ON_NULL_RETURN_VAL(ef, NULL); | ||
577 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL); | ||
578 | EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL); | ||
579 | EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL); | ||
580 | |||
581 | er = malloc(sizeof (Eio_Eet_Read)); | ||
582 | EINA_SAFETY_ON_NULL_RETURN_VAL(er, NULL); | ||
583 | |||
584 | er->ef = ef; | ||
585 | er->name = eina_stringshare_add(name); | ||
586 | er->cipher_key = eina_stringshare_add(cipher_key); | ||
587 | er->done_cb.read = done_cb; | ||
588 | er->result = NULL; | ||
589 | |||
590 | if (!eio_file_set(&er->common, | ||
591 | NULL, | ||
592 | error_cb, | ||
593 | data, | ||
594 | _eio_eet_read_cipher_job, | ||
595 | _eio_eet_read_cipher_end, | ||
596 | _eio_eet_read_cancel)) | ||
597 | return NULL; | ||
598 | return &er->common; | ||
599 | } | ||
600 | |||
601 | EAPI Eio_File * | ||
602 | eio_eet_write_cipher(Eet_File *ef, | ||
603 | const char *name, | ||
604 | void *write_data, | ||
605 | int size, | ||
606 | int compress, | ||
607 | const char *cipher_key, | ||
608 | Eio_Done_Int_Cb done_cb, | ||
609 | Eio_Error_Cb error_cb, | ||
610 | const void *user_data) | ||
611 | { | ||
612 | Eio_Eet_Write *ew; | ||
613 | |||
614 | EINA_SAFETY_ON_NULL_RETURN_VAL(ef, NULL); | ||
615 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL); | ||
616 | EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL); | ||
617 | EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL); | ||
618 | |||
619 | ew = malloc(sizeof (Eio_Eet_Write)); | ||
620 | EINA_SAFETY_ON_NULL_RETURN_VAL(ew, NULL); | ||
621 | |||
622 | ew->ef = ef; | ||
623 | ew->name = eina_stringshare_add(name); | ||
624 | ew->cipher_key = eina_stringshare_add(cipher_key); | ||
625 | ew->write_data = write_data; | ||
626 | ew->size = size; | ||
627 | ew->compress = compress; | ||
628 | ew->done_cb = done_cb; | ||
629 | ew->result = 0; | ||
630 | |||
631 | if (!eio_file_set(&ew->common, | ||
632 | NULL, | ||
633 | error_cb, | ||
634 | user_data, | ||
635 | _eio_eet_write_job, | ||
636 | _eio_eet_write_end, | ||
637 | _eio_eet_write_cancel)) | ||
638 | return NULL; | ||
639 | return &ew->common; | ||
640 | } | ||
diff --git a/src/lib/eio/eio_file.c b/src/lib/eio/eio_file.c new file mode 100644 index 0000000000..ffcd2a73ad --- /dev/null +++ b/src/lib/eio/eio_file.c | |||
@@ -0,0 +1,979 @@ | |||
1 | /* EIO - EFL data type library | ||
2 | * Copyright (C) 2010 Enlightenment Developers: | ||
3 | * Cedric Bail <cedric.bail@free.fr> | ||
4 | * Vincent "caro" Torri <vtorri at univ-evry dot fr> | ||
5 | * Stephen "okra" Houston <UnixTitan@gmail.com> | ||
6 | * | ||
7 | * This library is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This library is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library; | ||
19 | * if not, see <http://www.gnu.org/licenses/>. | ||
20 | */ | ||
21 | |||
22 | #include "eio_private.h" | ||
23 | #include "Eio.h" | ||
24 | |||
25 | #ifdef HAVE_XATTR | ||
26 | # include <sys/xattr.h> | ||
27 | #endif | ||
28 | |||
29 | /*============================================================================* | ||
30 | * Local * | ||
31 | *============================================================================*/ | ||
32 | |||
33 | /** | ||
34 | * @cond LOCAL | ||
35 | */ | ||
36 | |||
37 | static void | ||
38 | _eio_file_heavy(void *data, Ecore_Thread *thread) | ||
39 | { | ||
40 | Eio_File_Char_Ls *async = data; | ||
41 | Eina_Iterator *ls; | ||
42 | const char *file; | ||
43 | Eina_List *pack = NULL; | ||
44 | double start, current; | ||
45 | |||
46 | ls = eina_file_ls(async->ls.directory); | ||
47 | if (!ls) | ||
48 | { | ||
49 | eio_file_thread_error(&async->ls.common, thread); | ||
50 | return ; | ||
51 | } | ||
52 | |||
53 | eio_file_container_set(&async->ls.common, eina_iterator_container_get(ls)); | ||
54 | |||
55 | start = ecore_time_get(); | ||
56 | |||
57 | EINA_ITERATOR_FOREACH(ls, file) | ||
58 | { | ||
59 | Eina_Bool filter = EINA_TRUE; | ||
60 | |||
61 | if (async->filter_cb) | ||
62 | { | ||
63 | filter = async->filter_cb((void*) async->ls.common.data, &async->ls.common, file); | ||
64 | } | ||
65 | |||
66 | if (filter) | ||
67 | { | ||
68 | Eio_File_Char *send_fc; | ||
69 | |||
70 | send_fc = eio_char_malloc(); | ||
71 | if (!send_fc) goto on_error; | ||
72 | |||
73 | send_fc->filename = file; | ||
74 | send_fc->associated = async->ls.common.worker.associated; | ||
75 | async->ls.common.worker.associated = NULL; | ||
76 | |||
77 | pack = eina_list_append(pack, send_fc); | ||
78 | } | ||
79 | else | ||
80 | { | ||
81 | on_error: | ||
82 | eina_stringshare_del(file); | ||
83 | |||
84 | if (async->ls.common.worker.associated) | ||
85 | { | ||
86 | eina_hash_free(async->ls.common.worker.associated); | ||
87 | async->ls.common.worker.associated = NULL; | ||
88 | } | ||
89 | } | ||
90 | |||
91 | current = ecore_time_get(); | ||
92 | if (current - start > EIO_PACKED_TIME) | ||
93 | { | ||
94 | start = current; | ||
95 | ecore_thread_feedback(thread, pack); | ||
96 | pack = NULL; | ||
97 | } | ||
98 | |||
99 | if (ecore_thread_check(thread)) | ||
100 | break; | ||
101 | } | ||
102 | |||
103 | if (pack) ecore_thread_feedback(thread, pack); | ||
104 | |||
105 | eio_file_container_set(&async->ls.common, NULL); | ||
106 | |||
107 | eina_iterator_free(ls); | ||
108 | } | ||
109 | |||
110 | static void | ||
111 | _eio_file_notify(void *data, Ecore_Thread *thread EINA_UNUSED, void *msg_data) | ||
112 | { | ||
113 | Eio_File_Char_Ls *async = data; | ||
114 | Eina_List *pack = msg_data; | ||
115 | Eio_File_Char *info; | ||
116 | |||
117 | EINA_LIST_FREE(pack, info) | ||
118 | { | ||
119 | async->ls.common.main.associated = info->associated; | ||
120 | |||
121 | async->main_cb((void*) async->ls.common.data, | ||
122 | &async->ls.common, | ||
123 | info->filename); | ||
124 | |||
125 | if (async->ls.common.main.associated) | ||
126 | { | ||
127 | eina_hash_free(async->ls.common.main.associated); | ||
128 | async->ls.common.main.associated = NULL; | ||
129 | } | ||
130 | |||
131 | eina_stringshare_del(info->filename); | ||
132 | eio_char_free(info); | ||
133 | } | ||
134 | } | ||
135 | |||
136 | static void | ||
137 | _eio_file_eina_ls_heavy(Ecore_Thread *thread, Eio_File_Direct_Ls *async, Eina_Iterator *ls) | ||
138 | { | ||
139 | const Eina_File_Direct_Info *info; | ||
140 | Eina_List *pack = NULL; | ||
141 | double start, current; | ||
142 | |||
143 | if (!ls) | ||
144 | { | ||
145 | eio_file_thread_error(&async->ls.common, thread); | ||
146 | return ; | ||
147 | } | ||
148 | |||
149 | eio_file_container_set(&async->ls.common, eina_iterator_container_get(ls)); | ||
150 | |||
151 | start = ecore_time_get(); | ||
152 | |||
153 | EINA_ITERATOR_FOREACH(ls, info) | ||
154 | { | ||
155 | Eina_Bool filter = EINA_TRUE; | ||
156 | |||
157 | if (async->filter_cb) | ||
158 | { | ||
159 | filter = async->filter_cb((void*) async->ls.common.data, &async->ls.common, info); | ||
160 | } | ||
161 | |||
162 | if (filter) | ||
163 | { | ||
164 | Eio_File_Direct_Info *send_di; | ||
165 | |||
166 | send_di = eio_direct_info_malloc(); | ||
167 | if (!send_di) continue; | ||
168 | |||
169 | memcpy(&send_di->info, info, sizeof (Eina_File_Direct_Info)); | ||
170 | send_di->associated = async->ls.common.worker.associated; | ||
171 | async->ls.common.worker.associated = NULL; | ||
172 | |||
173 | pack = eina_list_append(pack, send_di); | ||
174 | } | ||
175 | else if (async->ls.common.worker.associated) | ||
176 | { | ||
177 | eina_hash_free(async->ls.common.worker.associated); | ||
178 | async->ls.common.worker.associated = NULL; | ||
179 | } | ||
180 | |||
181 | current = ecore_time_get(); | ||
182 | if (current - start > EIO_PACKED_TIME) | ||
183 | { | ||
184 | start = current; | ||
185 | ecore_thread_feedback(thread, pack); | ||
186 | pack = NULL; | ||
187 | } | ||
188 | |||
189 | if (ecore_thread_check(thread)) | ||
190 | break; | ||
191 | } | ||
192 | |||
193 | if (pack) ecore_thread_feedback(thread, pack); | ||
194 | |||
195 | eio_file_container_set(&async->ls.common, NULL); | ||
196 | |||
197 | eina_iterator_free(ls); | ||
198 | } | ||
199 | |||
200 | static void | ||
201 | _eio_file_direct_heavy(void *data, Ecore_Thread *thread) | ||
202 | { | ||
203 | Eio_File_Direct_Ls *async = data; | ||
204 | Eina_Iterator *ls; | ||
205 | |||
206 | ls = eina_file_direct_ls(async->ls.directory); | ||
207 | |||
208 | _eio_file_eina_ls_heavy(thread, async, ls); | ||
209 | } | ||
210 | |||
211 | static void | ||
212 | _eio_file_stat_heavy(void *data, Ecore_Thread *thread) | ||
213 | { | ||
214 | Eio_File_Direct_Ls *async = data; | ||
215 | Eina_Iterator *ls; | ||
216 | |||
217 | ls = eina_file_stat_ls(async->ls.directory); | ||
218 | |||
219 | _eio_file_eina_ls_heavy(thread, async, ls); | ||
220 | } | ||
221 | |||
222 | static void | ||
223 | _eio_file_direct_notify(void *data, Ecore_Thread *thread EINA_UNUSED, void *msg_data) | ||
224 | { | ||
225 | Eio_File_Direct_Ls *async = data; | ||
226 | Eina_List *pack = msg_data; | ||
227 | Eio_File_Direct_Info *info; | ||
228 | |||
229 | EINA_LIST_FREE(pack, info) | ||
230 | { | ||
231 | async->ls.common.main.associated = info->associated; | ||
232 | |||
233 | async->main_cb((void*) async->ls.common.data, | ||
234 | &async->ls.common, | ||
235 | &info->info); | ||
236 | |||
237 | if (async->ls.common.main.associated) | ||
238 | { | ||
239 | eina_hash_free(async->ls.common.main.associated); | ||
240 | async->ls.common.main.associated = NULL; | ||
241 | } | ||
242 | |||
243 | eio_direct_info_free(info); | ||
244 | } | ||
245 | } | ||
246 | |||
247 | static void | ||
248 | _eio_eina_file_copy_xattr(Ecore_Thread *thread EINA_UNUSED, | ||
249 | Eio_File_Progress *op EINA_UNUSED, | ||
250 | Eina_File *f, int out) | ||
251 | { | ||
252 | Eina_Iterator *it; | ||
253 | Eina_Xattr *attr; | ||
254 | |||
255 | it = eina_file_xattr_value_get(f); | ||
256 | EINA_ITERATOR_FOREACH(it, attr) | ||
257 | { | ||
258 | #ifdef HAVE_XATTR | ||
259 | fsetxattr(out, attr->name, attr->value, attr->length, 0); | ||
260 | #endif | ||
261 | } | ||
262 | eina_iterator_free(it); | ||
263 | } | ||
264 | |||
265 | #ifdef HAVE_XATTR | ||
266 | static void | ||
267 | _eio_file_copy_xattr(Ecore_Thread *thread EINA_UNUSED, | ||
268 | Eio_File_Progress *op EINA_UNUSED, | ||
269 | int in, int out) | ||
270 | { | ||
271 | char *tmp; | ||
272 | ssize_t length; | ||
273 | ssize_t i; | ||
274 | |||
275 | length = flistxattr(in, NULL, 0); | ||
276 | |||
277 | if (length <= 0) return ; | ||
278 | |||
279 | tmp = alloca(length); | ||
280 | length = flistxattr(in, tmp, length); | ||
281 | |||
282 | for (i = 0; i < length; i += strlen(tmp) + 1) | ||
283 | { | ||
284 | ssize_t attr_length; | ||
285 | void *value; | ||
286 | |||
287 | attr_length = fgetxattr(in, tmp, NULL, 0); | ||
288 | if (!attr_length) continue ; | ||
289 | |||
290 | value = malloc(attr_length); | ||
291 | if (!value) continue ; | ||
292 | attr_length = fgetxattr(in, tmp, value, attr_length); | ||
293 | |||
294 | if (attr_length > 0) | ||
295 | fsetxattr(out, tmp, value, attr_length, 0); | ||
296 | |||
297 | free(value); | ||
298 | } | ||
299 | } | ||
300 | #endif | ||
301 | |||
302 | static Eina_Bool | ||
303 | _eio_file_write(int fd, void *mem, ssize_t length) | ||
304 | { | ||
305 | ssize_t count; | ||
306 | |||
307 | if (length == 0) return EINA_TRUE; | ||
308 | |||
309 | count = write(fd, mem, length); | ||
310 | if (count != length) return EINA_FALSE; | ||
311 | return EINA_TRUE; | ||
312 | } | ||
313 | |||
314 | #ifndef MAP_HUGETLB | ||
315 | # define MAP_HUGETLB 0 | ||
316 | #endif | ||
317 | |||
318 | static Eina_Bool | ||
319 | _eio_file_copy_mmap(Ecore_Thread *thread, Eio_File_Progress *op, Eina_File *f, int out) | ||
320 | { | ||
321 | char *m = MAP_FAILED; | ||
322 | long long i; | ||
323 | long long size; | ||
324 | |||
325 | size = eina_file_size_get(f); | ||
326 | |||
327 | for (i = 0; i < size; i += EIO_PACKET_SIZE * EIO_PACKET_COUNT) | ||
328 | { | ||
329 | int j; | ||
330 | int k; | ||
331 | int c; | ||
332 | |||
333 | m = eina_file_map_new(f, EINA_FILE_SEQUENTIAL, | ||
334 | i, EIO_PACKET_SIZE * EIO_PACKET_COUNT); | ||
335 | if (!m) | ||
336 | goto on_error; | ||
337 | |||
338 | c = size - i; | ||
339 | if (c - EIO_PACKET_SIZE * EIO_PACKET_COUNT > 0) | ||
340 | c = EIO_PACKET_SIZE * EIO_PACKET_COUNT; | ||
341 | else | ||
342 | c = size - i; | ||
343 | |||
344 | for (j = EIO_PACKET_SIZE, k = 0; j < c; k = j, j += EIO_PACKET_SIZE) | ||
345 | { | ||
346 | if (!_eio_file_write(out, m + k, EIO_PACKET_SIZE)) | ||
347 | goto on_error; | ||
348 | |||
349 | eio_progress_send(thread, op, i + j, size); | ||
350 | } | ||
351 | |||
352 | if (!_eio_file_write(out, m + k, c - k)) | ||
353 | goto on_error; | ||
354 | |||
355 | if (eina_file_map_faulted(f, m)) | ||
356 | goto on_error; | ||
357 | |||
358 | eio_progress_send(thread, op, i + c, size); | ||
359 | |||
360 | eina_file_map_free(f, m); | ||
361 | m = NULL; | ||
362 | |||
363 | if (ecore_thread_check(thread)) | ||
364 | goto on_error; | ||
365 | } | ||
366 | |||
367 | return EINA_TRUE; | ||
368 | |||
369 | on_error: | ||
370 | if (m != NULL) eina_file_map_free(f, m); | ||
371 | return EINA_FALSE; | ||
372 | } | ||
373 | |||
374 | #ifdef HAVE_SPLICE | ||
375 | static int | ||
376 | _eio_file_copy_splice(Ecore_Thread *thread, Eio_File_Progress *op, int in, int out, long long size) | ||
377 | { | ||
378 | int result = 0; | ||
379 | long long count; | ||
380 | long long i; | ||
381 | int pipefd[2]; | ||
382 | |||
383 | if (pipe(pipefd) < 0) | ||
384 | return -1; | ||
385 | |||
386 | for (i = 0; i < size; i += count) | ||
387 | { | ||
388 | count = splice(in, 0, pipefd[1], NULL, EIO_PACKET_SIZE * EIO_PACKET_COUNT, SPLICE_F_MORE | SPLICE_F_MOVE); | ||
389 | if (count < 0) goto on_error; | ||
390 | |||
391 | count = splice(pipefd[0], NULL, out, 0, count, SPLICE_F_MORE | SPLICE_F_MOVE); | ||
392 | if (count < 0) goto on_error; | ||
393 | |||
394 | eio_progress_send(thread, op, i, size); | ||
395 | |||
396 | if (ecore_thread_check(thread)) | ||
397 | goto on_error; | ||
398 | } | ||
399 | |||
400 | result = 1; | ||
401 | |||
402 | on_error: | ||
403 | if (result != 1 && (errno == EBADF || errno == EINVAL)) result = -1; | ||
404 | close(pipefd[0]); | ||
405 | close(pipefd[1]); | ||
406 | |||
407 | return result; | ||
408 | } | ||
409 | #endif | ||
410 | |||
411 | static void | ||
412 | _eio_file_copy_heavy(void *data, Ecore_Thread *thread) | ||
413 | { | ||
414 | Eio_File_Progress *copy = data; | ||
415 | |||
416 | eio_file_copy_do(thread, copy); | ||
417 | } | ||
418 | |||
419 | static void | ||
420 | _eio_file_copy_notify(void *data, Ecore_Thread *thread EINA_UNUSED, void *msg_data) | ||
421 | { | ||
422 | Eio_File_Progress *copy = data; | ||
423 | |||
424 | eio_progress_cb(msg_data, copy); | ||
425 | } | ||
426 | |||
427 | static void | ||
428 | _eio_file_copy_free(Eio_File_Progress *copy) | ||
429 | { | ||
430 | eina_stringshare_del(copy->source); | ||
431 | eina_stringshare_del(copy->dest); | ||
432 | eio_file_free(©->common); | ||
433 | } | ||
434 | |||
435 | static void | ||
436 | _eio_file_copy_end(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
437 | { | ||
438 | Eio_File_Progress *copy = data; | ||
439 | |||
440 | copy->common.done_cb((void*) copy->common.data, ©->common); | ||
441 | |||
442 | _eio_file_copy_free(copy); | ||
443 | } | ||
444 | |||
445 | static void | ||
446 | _eio_file_copy_error(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
447 | { | ||
448 | Eio_File_Progress *copy = data; | ||
449 | |||
450 | eio_file_error(©->common); | ||
451 | |||
452 | _eio_file_copy_free(copy); | ||
453 | } | ||
454 | |||
455 | static void | ||
456 | _eio_file_move_free(Eio_File_Move *move) | ||
457 | { | ||
458 | eina_stringshare_del(move->progress.source); | ||
459 | eina_stringshare_del(move->progress.dest); | ||
460 | eio_file_free(&move->progress.common); | ||
461 | } | ||
462 | |||
463 | static void | ||
464 | _eio_file_move_copy_progress(void *data, Eio_File *handler EINA_UNUSED, const Eio_Progress *info) | ||
465 | { | ||
466 | Eio_File_Move *move = data; | ||
467 | |||
468 | move->progress.progress_cb((void*) move->progress.common.data, &move->progress.common, info); | ||
469 | } | ||
470 | |||
471 | static void | ||
472 | _eio_file_move_unlink_done(void *data, Eio_File *handler EINA_UNUSED) | ||
473 | { | ||
474 | Eio_File_Move *move = data; | ||
475 | |||
476 | move->progress.common.done_cb((void*) move->progress.common.data, &move->progress.common); | ||
477 | |||
478 | _eio_file_move_free(move); | ||
479 | } | ||
480 | |||
481 | static void | ||
482 | _eio_file_move_unlink_error(void *data, Eio_File *handler EINA_UNUSED, int error) | ||
483 | { | ||
484 | Eio_File_Move *move = data; | ||
485 | |||
486 | move->copy = NULL; | ||
487 | |||
488 | move->progress.common.error = error; | ||
489 | eio_file_error(&move->progress.common); | ||
490 | |||
491 | _eio_file_move_free(move); | ||
492 | } | ||
493 | |||
494 | static void | ||
495 | _eio_file_move_copy_done(void *data, Eio_File *handler EINA_UNUSED) | ||
496 | { | ||
497 | Eio_File_Move *move = data; | ||
498 | Eio_File *rm; | ||
499 | |||
500 | rm = eio_file_unlink(move->progress.source, | ||
501 | _eio_file_move_unlink_done, | ||
502 | _eio_file_move_unlink_error, | ||
503 | move); | ||
504 | if (rm) move->copy = rm; | ||
505 | } | ||
506 | |||
507 | static void | ||
508 | _eio_file_move_copy_error(void *data, Eio_File *handler EINA_UNUSED, int error) | ||
509 | { | ||
510 | Eio_File_Move *move = data; | ||
511 | |||
512 | move->progress.common.error = error; | ||
513 | eio_file_error(&move->progress.common); | ||
514 | |||
515 | _eio_file_move_free(move); | ||
516 | } | ||
517 | |||
518 | static void | ||
519 | _eio_file_move_heavy(void *data, Ecore_Thread *thread) | ||
520 | { | ||
521 | Eio_File_Move *move = data; | ||
522 | |||
523 | if (rename(move->progress.source, move->progress.dest) < 0) | ||
524 | eio_file_thread_error(&move->progress.common, thread); | ||
525 | else | ||
526 | eio_progress_send(thread, &move->progress, 1, 1); | ||
527 | } | ||
528 | |||
529 | static void | ||
530 | _eio_file_move_notify(void *data, Ecore_Thread *thread EINA_UNUSED, void *msg_data) | ||
531 | { | ||
532 | Eio_File_Move *move = data; | ||
533 | |||
534 | eio_progress_cb(msg_data, &move->progress); | ||
535 | } | ||
536 | |||
537 | static void | ||
538 | _eio_file_move_end(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
539 | { | ||
540 | Eio_File_Move *move = data; | ||
541 | |||
542 | move->progress.common.done_cb((void*) move->progress.common.data, &move->progress.common); | ||
543 | |||
544 | _eio_file_move_free(move); | ||
545 | } | ||
546 | |||
547 | static void | ||
548 | _eio_file_move_error(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
549 | { | ||
550 | Eio_File_Move *move = data; | ||
551 | |||
552 | if (move->copy) | ||
553 | { | ||
554 | eio_file_cancel(move->copy); | ||
555 | return ; | ||
556 | } | ||
557 | |||
558 | if (move->progress.common.error == EXDEV) | ||
559 | { | ||
560 | Eio_File *eio_cp; | ||
561 | |||
562 | eio_cp = eio_file_copy(move->progress.source, move->progress.dest, | ||
563 | move->progress.progress_cb ? _eio_file_move_copy_progress : NULL, | ||
564 | _eio_file_move_copy_done, | ||
565 | _eio_file_move_copy_error, | ||
566 | move); | ||
567 | |||
568 | if (eio_cp) | ||
569 | { | ||
570 | move->copy = eio_cp; | ||
571 | |||
572 | move->progress.common.thread = ((Eio_File_Progress*)move->copy)->common.thread; | ||
573 | return ; | ||
574 | } | ||
575 | } | ||
576 | |||
577 | eio_file_error(&move->progress.common); | ||
578 | |||
579 | _eio_file_move_free(move); | ||
580 | } | ||
581 | |||
582 | /** | ||
583 | * @endcond | ||
584 | */ | ||
585 | |||
586 | |||
587 | /*============================================================================* | ||
588 | * Global * | ||
589 | *============================================================================*/ | ||
590 | |||
591 | /** | ||
592 | * @cond LOCAL | ||
593 | */ | ||
594 | |||
595 | void | ||
596 | eio_progress_cb(Eio_Progress *progress, Eio_File_Progress *op) | ||
597 | { | ||
598 | op->progress_cb((void *) op->common.data, &op->common, progress); | ||
599 | |||
600 | eio_progress_free(progress); | ||
601 | } | ||
602 | |||
603 | Eina_Bool | ||
604 | eio_file_copy_do(Ecore_Thread *thread, Eio_File_Progress *copy) | ||
605 | { | ||
606 | Eina_File *f; | ||
607 | #ifdef HAVE_SPLICE | ||
608 | struct stat buf; | ||
609 | int in = -1; | ||
610 | #endif | ||
611 | mode_t md; | ||
612 | int result = -1; | ||
613 | int out = -1; | ||
614 | |||
615 | #ifdef HAVE_SPLICE | ||
616 | in = open(copy->source, O_RDONLY); | ||
617 | if (in < 0) | ||
618 | { | ||
619 | eio_file_thread_error(©->common, thread); | ||
620 | return EINA_FALSE; | ||
621 | } | ||
622 | |||
623 | /* | ||
624 | As we need file size for progression information and both copy method | ||
625 | call fstat (better than stat as it avoid race condition). | ||
626 | */ | ||
627 | if (fstat(in, &buf) < 0) | ||
628 | goto on_error; | ||
629 | |||
630 | md = buf.st_mode; | ||
631 | #endif | ||
632 | |||
633 | /* open write */ | ||
634 | out = open(copy->dest, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); | ||
635 | if (out < 0) | ||
636 | goto on_error; | ||
637 | |||
638 | #ifdef HAVE_SPLICE | ||
639 | /* fast file copy code using Linux splice API */ | ||
640 | result = _eio_file_copy_splice(thread, copy, in, out, buf.st_size); | ||
641 | if (result == 0) | ||
642 | goto on_error; | ||
643 | #endif | ||
644 | |||
645 | /* classic copy method using mmap and write */ | ||
646 | if (result == -1) | ||
647 | { | ||
648 | #ifndef HAVE_SPLICE | ||
649 | struct stat buf; | ||
650 | |||
651 | if (stat(copy->source, &buf) < 0) | ||
652 | goto on_error; | ||
653 | |||
654 | md = buf.st_mode; | ||
655 | #endif | ||
656 | |||
657 | f = eina_file_open(copy->source, 0); | ||
658 | if (!f) goto on_error; | ||
659 | |||
660 | if (!_eio_file_copy_mmap(thread, copy, f, out)) | ||
661 | { | ||
662 | eina_file_close(f); | ||
663 | goto on_error; | ||
664 | } | ||
665 | |||
666 | _eio_eina_file_copy_xattr(thread, copy, f, out); | ||
667 | |||
668 | eina_file_close(f); | ||
669 | } | ||
670 | else | ||
671 | { | ||
672 | #if defined HAVE_XATTR && defined HAVE_SPLICE | ||
673 | _eio_file_copy_xattr(thread, copy, in, out); | ||
674 | #endif | ||
675 | } | ||
676 | |||
677 | /* change access right to match source */ | ||
678 | #ifdef HAVE_CHMOD | ||
679 | if (fchmod(out, md) != 0) | ||
680 | goto on_error; | ||
681 | #else | ||
682 | if (chmod(copy->dest, md) != 0) | ||
683 | goto on_error; | ||
684 | #endif | ||
685 | |||
686 | close(out); | ||
687 | #ifdef HAVE_SPLICE | ||
688 | close(in); | ||
689 | #endif | ||
690 | |||
691 | return EINA_TRUE; | ||
692 | |||
693 | on_error: | ||
694 | eio_file_thread_error(©->common, thread); | ||
695 | |||
696 | #ifdef HAVE_SPLICE | ||
697 | if (in >= 0) close(in); | ||
698 | #endif | ||
699 | if (out >= 0) close(out); | ||
700 | if (out >= 0) | ||
701 | unlink(copy->dest); | ||
702 | return EINA_FALSE; | ||
703 | } | ||
704 | |||
705 | void | ||
706 | eio_async_free(Eio_File_Ls *async) | ||
707 | { | ||
708 | eina_stringshare_del(async->directory); | ||
709 | eio_file_free(&async->common); | ||
710 | } | ||
711 | |||
712 | void | ||
713 | eio_async_end(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
714 | { | ||
715 | Eio_File_Ls *async = data; | ||
716 | |||
717 | async->common.done_cb((void*) async->common.data, &async->common); | ||
718 | |||
719 | eio_async_free(async); | ||
720 | } | ||
721 | |||
722 | void | ||
723 | eio_async_error(void *data, Ecore_Thread *thread EINA_UNUSED) | ||
724 | { | ||
725 | Eio_File_Ls *async = data; | ||
726 | |||
727 | eio_file_error(&async->common); | ||
728 | |||
729 | eio_async_free(async); | ||
730 | } | ||
731 | |||
732 | /** | ||
733 | * @endcond | ||
734 | */ | ||
735 | |||
736 | |||
737 | /*============================================================================* | ||
738 | * API * | ||
739 | *============================================================================*/ | ||
740 | |||
741 | EAPI Eio_File * | ||
742 | eio_file_ls(const char *dir, | ||
743 | Eio_Filter_Cb filter_cb, | ||
744 | Eio_Main_Cb main_cb, | ||
745 | Eio_Done_Cb done_cb, | ||
746 | Eio_Error_Cb error_cb, | ||
747 | const void *data) | ||
748 | { | ||
749 | Eio_File_Char_Ls *async; | ||
750 | |||
751 | EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL); | ||
752 | EINA_SAFETY_ON_NULL_RETURN_VAL(main_cb, NULL); | ||
753 | EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL); | ||
754 | EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL); | ||
755 | |||
756 | async = malloc(sizeof (Eio_File_Char_Ls)); | ||
757 | EINA_SAFETY_ON_NULL_RETURN_VAL(async, NULL); | ||
758 | |||
759 | async->filter_cb = filter_cb; | ||
760 | async->main_cb = main_cb; | ||
761 | async->ls.directory = eina_stringshare_add(dir); | ||
762 | |||
763 | if (!eio_long_file_set(&async->ls.common, | ||
764 | done_cb, | ||
765 | error_cb, | ||
766 | data, | ||
767 | _eio_file_heavy, | ||
768 | _eio_file_notify, | ||
769 | eio_async_end, | ||
770 | eio_async_error)) | ||
771 | return NULL; | ||
772 | |||
773 | return &async->ls.common; | ||
774 | } | ||
775 | |||
776 | EAPI Eio_File * | ||
777 | eio_file_direct_ls(const char *dir, | ||
778 | Eio_Filter_Direct_Cb filter_cb, | ||
779 | Eio_Main_Direct_Cb main_cb, | ||
780 | Eio_Done_Cb done_cb, | ||
781 | Eio_Error_Cb error_cb, | ||
782 | const void *data) | ||
783 | { | ||
784 | Eio_File_Direct_Ls *async; | ||
785 | |||
786 | EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL); | ||
787 | EINA_SAFETY_ON_NULL_RETURN_VAL(main_cb, NULL); | ||
788 | EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL); | ||
789 | EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL); | ||
790 | |||
791 | async = malloc(sizeof(Eio_File_Direct_Ls)); | ||
792 | EINA_SAFETY_ON_NULL_RETURN_VAL(async, NULL); | ||
793 | |||
794 | async->filter_cb = filter_cb; | ||
795 | async->main_cb = main_cb; | ||
796 | async->ls.directory = eina_stringshare_add(dir); | ||
797 | |||
798 | if (!eio_long_file_set(&async->ls.common, | ||
799 | done_cb, | ||
800 | error_cb, | ||
801 | data, | ||
802 | _eio_file_direct_heavy, | ||
803 | _eio_file_direct_notify, | ||
804 | eio_async_end, | ||
805 | eio_async_error)) | ||
806 | return NULL; | ||
807 | |||
808 | return &async->ls.common; | ||
809 | } | ||
810 | |||
811 | EAPI Eio_File * | ||
812 | eio_file_stat_ls(const char *dir, | ||
813 | Eio_Filter_Direct_Cb filter_cb, | ||
814 | Eio_Main_Direct_Cb main_cb, | ||
815 | Eio_Done_Cb done_cb, | ||
816 | Eio_Error_Cb error_cb, | ||
817 | const void *data) | ||
818 | { | ||
819 | Eio_File_Direct_Ls *async; | ||
820 | |||
821 | EINA_SAFETY_ON_NULL_RETURN_VAL(dir, NULL); | ||
822 | EINA_SAFETY_ON_NULL_RETURN_VAL(main_cb, NULL); | ||
823 | EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL); | ||
824 | EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL); | ||
825 | |||
826 | async = malloc(sizeof(Eio_File_Direct_Ls)); | ||
827 | EINA_SAFETY_ON_NULL_RETURN_VAL(async, NULL); | ||
828 | |||
829 | async->filter_cb = filter_cb; | ||
830 | async->main_cb = main_cb; | ||
831 | async->ls.directory = eina_stringshare_add(dir); | ||
832 | |||
833 | if (!eio_long_file_set(&async->ls.common, | ||
834 | done_cb, | ||
835 | error_cb, | ||
836 | data, | ||
837 | _eio_file_stat_heavy, | ||
838 | _eio_file_direct_notify, | ||
839 | eio_async_end, | ||
840 | eio_async_error)) | ||
841 | return NULL; | ||
842 | |||
843 | return &async->ls.common; | ||
844 | } | ||
845 | |||
846 | EAPI Eina_Bool | ||
847 | eio_file_cancel(Eio_File *ls) | ||
848 | { | ||
849 | EINA_SAFETY_ON_NULL_RETURN_VAL(ls, EINA_FALSE); | ||
850 | return ecore_thread_cancel(ls->thread); | ||
851 | } | ||
852 | |||
853 | EAPI Eina_Bool | ||
854 | eio_file_check(Eio_File *ls) | ||
855 | { | ||
856 | EINA_SAFETY_ON_NULL_RETURN_VAL(ls, EINA_TRUE); | ||
857 | return ecore_thread_check(ls->thread); | ||
858 | } | ||
859 | |||
860 | EAPI void * | ||
861 | eio_file_container_get(Eio_File *ls) | ||
862 | { | ||
863 | EINA_SAFETY_ON_NULL_RETURN_VAL(ls, EINA_FALSE); | ||
864 | return ls->container; | ||
865 | } | ||
866 | |||
867 | EAPI Eina_Bool | ||
868 | eio_file_associate_add(Eio_File *ls, | ||
869 | const char *key, | ||
870 | const void *data, Eina_Free_Cb free_cb) | ||
871 | { | ||
872 | /* FIXME: Check if we are in the right worker thred */ | ||
873 | if (!ls->worker.associated) | ||
874 | ls->worker.associated = eina_hash_string_small_new(eio_associate_free); | ||
875 | |||
876 | return eina_hash_add(ls->worker.associated, | ||
877 | key, | ||
878 | eio_associate_malloc(data, free_cb)); | ||
879 | } | ||
880 | |||
881 | EAPI Eina_Bool | ||
882 | eio_file_associate_direct_add(Eio_File *ls, | ||
883 | const char *key, | ||
884 | const void *data, Eina_Free_Cb free_cb) | ||
885 | { | ||
886 | /* FIXME: Check if we are in the right worker thred */ | ||
887 | if (!ls->worker.associated) | ||
888 | ls->worker.associated = eina_hash_string_small_new(eio_associate_free); | ||
889 | |||
890 | return eina_hash_direct_add(ls->worker.associated, | ||
891 | key, | ||
892 | eio_associate_malloc(data, free_cb)); | ||
893 | } | ||
894 | |||
895 | EAPI void * | ||
896 | eio_file_associate_find(Eio_File *ls, const char *key) | ||
897 | { | ||
898 | Eio_File_Associate *search; | ||
899 | |||
900 | if (!ls->main.associated) | ||
901 | return NULL; | ||
902 | |||
903 | search = eina_hash_find(ls->main.associated, key); | ||
904 | if (!search) return NULL; | ||
905 | return search->data; | ||
906 | } | ||
907 | |||
908 | EAPI Eio_File * | ||
909 | eio_file_copy(const char *source, | ||
910 | const char *dest, | ||
911 | Eio_Progress_Cb progress_cb, | ||
912 | Eio_Done_Cb done_cb, | ||
913 | Eio_Error_Cb error_cb, | ||
914 | const void *data) | ||
915 | { | ||
916 | Eio_File_Progress *copy; | ||
917 | |||
918 | EINA_SAFETY_ON_NULL_RETURN_VAL(source, NULL); | ||
919 | EINA_SAFETY_ON_NULL_RETURN_VAL(dest, NULL); | ||
920 | EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL); | ||
921 | EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL); | ||
922 | |||
923 | copy = malloc(sizeof(Eio_File_Progress)); | ||
924 | EINA_SAFETY_ON_NULL_RETURN_VAL(copy, NULL); | ||
925 | |||
926 | copy->op = EIO_FILE_COPY; | ||
927 | copy->progress_cb = progress_cb; | ||
928 | copy->source = eina_stringshare_add(source); | ||
929 | copy->dest = eina_stringshare_add(dest); | ||
930 | |||
931 | if (!eio_long_file_set(©->common, | ||
932 | done_cb, | ||
933 | error_cb, | ||
934 | data, | ||
935 | _eio_file_copy_heavy, | ||
936 | _eio_file_copy_notify, | ||
937 | _eio_file_copy_end, | ||
938 | _eio_file_copy_error)) | ||
939 | return NULL; | ||
940 | |||
941 | return ©->common; | ||
942 | } | ||
943 | |||
944 | EAPI Eio_File * | ||
945 | eio_file_move(const char *source, | ||
946 | const char *dest, | ||
947 | Eio_Progress_Cb progress_cb, | ||
948 | Eio_Done_Cb done_cb, | ||
949 | Eio_Error_Cb error_cb, | ||
950 | const void *data) | ||
951 | { | ||
952 | Eio_File_Move *move; | ||
953 | |||
954 | EINA_SAFETY_ON_NULL_RETURN_VAL(source, NULL); | ||
955 | EINA_SAFETY_ON_NULL_RETURN_VAL(dest, NULL); | ||
956 | EINA_SAFETY_ON_NULL_RETURN_VAL(done_cb, NULL); | ||
957 | EINA_SAFETY_ON_NULL_RETURN_VAL(error_cb, NULL); | ||
958 | |||
959 | move = malloc(sizeof(Eio_File_Move)); | ||
960 | EINA_SAFETY_ON_NULL_RETURN_VAL(move, NULL); | ||
961 | |||
962 | move->progress.op = EIO_FILE_MOVE; | ||
963 | move->progress.progress_cb = progress_cb; | ||
964 | move->progress.source = eina_stringshare_add(source); | ||
965 | move->progress.dest = eina_stringshare_add(dest); | ||
966 | move->copy = NULL; | ||
967 | |||
968 | if (!eio_long_file_set(&move->progress.common, | ||
969 | done_cb, | ||
970 | error_cb, | ||
971 | data, | ||
972 | _eio_file_move_heavy, | ||
973 | _eio_file_move_notify, | ||
974 | _eio_file_move_end, | ||
975 | _eio_file_move_error)) | ||
976 | return NULL; | ||
977 | |||
978 | return &move->progress.common; | ||
979 | } | ||
diff --git a/src/lib/eio/eio_inline_helper.x b/src/lib/eio/eio_inline_helper.x new file mode 100644 index 0000000000..af49646b72 --- /dev/null +++ b/src/lib/eio/eio_inline_helper.x | |||
@@ -0,0 +1,105 @@ | |||
1 | /* EIO - EFL data type library | ||
2 | * Copyright (C) 2010 Enlightenment Developers: | ||
3 | * Cedric Bail <cedric.bail@free.fr> | ||
4 | * Vincent "caro" Torri <vtorri at univ-evry dot fr> | ||
5 | * Stephen "okra" Houston <unixtitan@gmail.com> | ||
6 | * | ||
7 | * This library is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This library is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library; | ||
19 | * if not, see <http://www.gnu.org/licenses/>. | ||
20 | */ | ||
21 | |||
22 | #ifndef EIO_INLINE_HELPER_H__ | ||
23 | # define EIO_INLINE_HELPER_H__ | ||
24 | |||
25 | /** | ||
26 | * @addtogroup Eio_Helper | ||
27 | * | ||
28 | * @{ | ||
29 | */ | ||
30 | |||
31 | /** | ||