1 #ifndef EIO_PRIVATE_H_
2 #define EIO_PRIVATE_H_
3
4 #ifdef HAVE_CONFIG_H
5 # include "config.h"
6 #endif
7
8 #ifdef STDC_HEADERS
9 # include <stdlib.h>
10 # include <stddef.h>
11 #else
12 # ifdef HAVE_STDLIB_H
13 # include <stdlib.h>
14 # endif
15 #endif
16
17 #include <sys/types.h>
18
19 #include <libgen.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <ctype.h>
23 #include <errno.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <unistd.h>
27 #include <fcntl.h>
28
29 #ifdef HAVE_FEATURES_H
30 # include <features.h>
31 #endif
32
33 #include <Ecore.h>
34
35 #include "Eio.h"
36
37 #ifdef _WIN32
38 # ifdef _WIN64
39 typedef struct __stat64 _eio_stat_t;
40 # define _eio_stat(p, b) _stat64(p, b)
41 # define _eio_lstat(p, b) _stat64(p, b)
42 # else
43 typedef struct _stat _eio_stat_t;
44 # define _eio_stat(p, b) _stat(p, b)
45 # define _eio_lstat(p, b) _stat(p, b)
46 # endif
47 #else
48 typedef struct stat _eio_stat_t;
49 # define _eio_stat(p, b) stat(p, b)
50 # define _eio_lstat(p, b) lstat(p, b)
51
52 # include <grp.h>
53 # include <pwd.h>
54 #endif
55
56 /* Keeping 8 Eio_File_Progress alive should be enough */
57 #define EIO_PROGRESS_LIMIT 8
58
59 /* Huge TLB == 16M on most system */
60 #define EIO_PACKET_SIZE 65536
61 #define EIO_PACKET_COUNT 256
62
63 #define EIO_PACKED_TIME 0.003
64
65 extern int _eio_log_dom_global;
66
67 #ifdef EIO_DEFAULT_LOG_COLOR
68 # undef EIO_DEFAULT_LOG_COLOR
69 #endif /* ifdef EIO_DEFAULT_LOG_COLOR */
70 #define EIO_DEFAULT_LOG_COLOR EINA_COLOR_CYAN
71 #ifdef ERR
72 # undef ERR
73 #endif /* ifdef ERR */
74 #define ERR(...) EINA_LOG_DOM_ERR(_eio_log_dom_global, __VA_ARGS__)
75 #ifdef DBG
76 # undef DBG
77 #endif /* ifdef DBG */
78 #define DBG(...) EINA_LOG_DOM_DBG(_eio_log_dom_global, __VA_ARGS__)
79 #ifdef INF
80 # undef INF
81 #endif /* ifdef INF */
82 #define INF(...) EINA_LOG_DOM_INFO(_eio_log_dom_global, __VA_ARGS__)
83 #ifdef WRN
84 # undef WRN
85 #endif /* ifdef WRN */
86 #define WRN(...) EINA_LOG_DOM_WARN(_eio_log_dom_global, __VA_ARGS__)
87 #ifdef CRI
88 # undef CRI
89 #endif /* ifdef CRI */
90 #define CRI(...) EINA_LOG_DOM_CRIT(_eio_log_dom_global, __VA_ARGS__)
91
92 typedef void (*Eio_Array_Cb)(void *data, Eio_File *common, Eina_Array *g);
93
94 typedef struct _Eio_Eet_Open Eio_Eet_Open;
95 typedef struct _Eio_Eet_Simple Eio_Eet_Simple;
96 typedef struct _Eio_Eet_Write Eio_Eet_Write;
97 typedef struct _Eio_Eet_Read Eio_Eet_Read;
98 typedef struct _Eio_Eet_Image_Write Eio_Eet_Image_Write;
99 typedef struct _Eio_File_Map Eio_File_Map;
100 typedef struct _Eio_File_Map_Rule Eio_File_Map_Rule;
101 typedef struct _Eio_File_Ls Eio_File_Ls;
102 typedef struct _Eio_File_Direct_Ls Eio_File_Direct_Ls;
103 typedef struct _Eio_File_Dir_Ls Eio_File_Dir_Ls;
104 typedef struct _Eio_File_Char_Ls Eio_File_Char_Ls;
105 typedef struct _Eio_File_Mkdir Eio_File_Mkdir;
106 typedef struct _Eio_File_Mkdir Eio_File_Chmod;
107 typedef struct _Eio_File_Unlink Eio_File_Unlink;
108 typedef struct _Eio_File_Stat Eio_File_Stat;
109 typedef struct _Eio_File_Progress Eio_File_Progress;
110 typedef struct _Eio_File_Move Eio_File_Move;
111 typedef struct _Eio_File_Chown Eio_File_Chown;
112 typedef struct _Eio_Monitor_Backend Eio_Monitor_Backend;
113
114 typedef struct _Eio_File_Xattr Eio_File_Xattr;
115
116 typedef struct _Eio_Dir_Copy Eio_Dir_Copy;
117
118 typedef struct _Eio_File_Direct_Info Eio_File_Direct_Info;
119 typedef struct _Eio_File_Char Eio_File_Char;
120
121 typedef struct _Eio_File_Associate Eio_File_Associate;
122
123 struct _Eio_File_Associate
124 {
125 void *data;
126
127 Eina_Free_Cb free_cb;
128 };
129
130 struct _Eio_File_Direct_Info
131 {
132 // Do not put anything before info
133 Eina_File_Direct_Info info;
134
135 Eina_Hash *associated;
136 };
137
138 struct _Eio_File_Char
139 {
140 const char *filename;
141
142 Eina_Hash *associated;
143 };
144
145 struct _Eio_File
146 {
147 Ecore_Thread *thread;
148 const void *data;
149 void *container;
150
151 int error;
152
153 Eio_Error_Cb error_cb;
154 Eio_Done_Cb done_cb;
155
156 struct {
157 Eina_Hash *associated;
158 } worker, main;
159
160 uint64_t length;
161 };
162
163 struct _Eio_Eet_Simple
164 {
165 Eio_File common;
166
167 Eet_File *ef;
168 Eio_Eet_Error_Cb error_cb;
169 Eet_Error error;
170 };
171
172 struct _Eio_Eet_Write
173 {
174 Eio_File common;
175
176 Eet_File *ef;
177 Eet_Data_Descriptor *edd;
178 const char *name;
179 const char *cipher_key;
180 void *write_data;
181 int compress;
182 int size;
183
184 int result;
185 Eio_Done_Int_Cb done_cb;
186 };
187
188 struct _Eio_Eet_Read
189 {
190 Eio_File common;
191
192 Eet_File *ef;
193 Eet_Data_Descriptor *edd;
194 const char *name;
195 const char *cipher_key;
196
197 int size;
198
199 void *result;
200 union {
201 Eio_Done_ERead_Cb eread;
202 Eio_Done_Data_Cb data;
203 Eio_Done_Read_Cb read;
204 } done_cb;
205 };
206
207 struct _Eio_Eet_Image_Write
208 {
209 Eio_File common;
210
211 Eet_File *ef;
212 const char *name;
213 const char *cipher_key;
214 void *write_data;
215
216 unsigned int w;
217 unsigned int h;
218 int alpha;
219 int compress;
220 int quality;
221 int lossy;
222
223 int result;
224 Eio_Done_Int_Cb done_cb;
225 };
226
227 struct _Eio_Eet_Open
228 {
229 Eio_File common;
230
231 Eio_Eet_Open_Cb eet_cb;
232 const char *filename;
233 Eet_File_Mode mode;
234
235 Eet_File *result;
236 };
237
238 struct _Eio_File_Map
239 {
240 Eio_File common;
241
242 Eio_Open_Cb open_cb;
243 const char *name;
244 Eina_Bool shared;
245
246 Eina_File *result;
247 };
248
249 struct _Eio_File_Map_Rule
250 {
251 Eio_File common;
252 Eio_Filter_Map_Cb filter_cb;
253 Eio_Map_Cb map_cb;
254
255 Eina_File_Populate rule;
256 Eina_File *file;
257
258 unsigned long int offset;
259 unsigned long int length;
260
261 void *result;
262 };
263
264 struct _Eio_File_Ls
265 {
266 Eio_File common;
267 const char *directory;
268 Eina_Iterator *ls;
269
270 Eina_Bool gather;
271 };
272
273 struct _Eio_File_Direct_Ls
274 {
275 Eio_File_Ls ls;
276
277 Eio_Filter_Direct_Cb filter_cb;
278 union {
279 Eio_Main_Direct_Cb main_cb;
280 Eio_Array_Cb main_internal_cb;
281 };
282
283 Eina_List *pack;
284 double start;
285 };
286
287 struct _Eio_File_Dir_Ls
288 {
289 Eio_File_Ls ls;
290
291 Eio_Filter_Dir_Cb filter_cb;
292 union {
293 Eio_Main_Direct_Cb main_cb;
294 Eio_Array_Cb main_internal_cb;
295 };
296
297 Eina_List *pack;
298 double start;
299 };
300
301 struct _Eio_File_Char_Ls
302 {
303 Eio_File_Ls ls;
304
305 Eio_Filter_Cb filter_cb;
306 union {
307 Eio_Main_Cb main_cb;
308 Eio_Array_Cb main_internal_cb;
309 };
310 };
311
312 struct _Eio_File_Mkdir
313 {
314 Eio_File common;
315
316 const char *path;
317 mode_t mode;
318 };
319
320 struct _Eio_File_Unlink
321 {
322 Eio_File common;
323
324 const char *path;
325 };
326
327 struct _Eio_File_Stat
328 {
329 Eio_File common;
330
331 Eio_Stat_Cb done_cb;
332
333 Eina_Stat buffer;
334 const char *path;
335 };
336
337 typedef enum {
338 EIO_XATTR_DATA,
339 EIO_XATTR_STRING,
340 EIO_XATTR_DOUBLE,
341 EIO_XATTR_INT
342 } Eio_File_Xattr_Op;
343
344 struct _Eio_File_Xattr
345 {
346 Eio_File common;
347
348 const char *path;
349 const char *attribute;
350 Eina_Xattr_Flags flags;
351
352 Eio_File_Xattr_Op op;
353
354 union {
355 struct {
356 Eio_Done_Data_Cb done_cb;
357
358 char *xattr_data;
359 ssize_t xattr_size;
360 } xdata;
361 struct {
362 Eio_Done_String_Cb done_cb;
363
364 char *xattr_string;
365 } xstring;
366 struct {
367 Eio_Done_Double_Cb done_cb;
368
369 double xattr_double;
370 } xdouble;
371 struct {
372 Eio_Done_Int_Cb done_cb;
373
374 int xattr_int;
375 } xint;
376 } todo;
377
378 Eina_Bool set : 1;
379 };
380
381 struct _Eio_File_Progress
382 {
383 Eio_File common;
384
385 Eio_Progress_Cb progress_cb;
386
387 const char *source;
388 const char *dest;
389
390 Eio_File_Op op;
391 };
392
393 struct _Eio_File_Move
394 {
395 Eio_File_Progress progress;
396
397 Eio_File *copy;
398 };
399
400 struct _Eio_Dir_Copy
401 {
402 Eio_File_Progress progress;
403 Eio_Filter_Direct_Cb filter_cb;
404
405 Eina_List *files;
406 Eina_List *dirs;
407 Eina_List *links;
408 };
409
410 struct _Eio_File_Chown
411 {
412 Eio_File common;
413
414 const char *path;
415 const char *user;
416 const char *group;
417 };
418
419 struct _Eio_Monitor
420 {
421 Eio_Monitor_Backend *backend;
422 Eio_File *exist;
423
424 const char *path;
425
426 EINA_REFCOUNT;
427 int error;
428
429 time_t mtime;
430
431 Eina_Bool fallback : 1;
432 Eina_Bool rename : 1;
433 Eina_Bool delete_me : 1;
434 };
435
436 /* Be aware that ecore_thread_run could call cancel_cb if something goes wrong. */
437 Eina_Bool eio_file_set(Eio_File *common,
438 Eio_Done_Cb done_cb,
439 Eio_Error_Cb error_cb,
440 const void *data,
441 Ecore_Thread_Cb job_cb,
442 Ecore_Thread_Cb end_cb,
443 Ecore_Thread_Cb cancel_cb);
444
445 /* Be aware that ecore_thread_run could call cancel_cb if something goes wrong. */
446 Eina_Bool eio_long_file_set(Eio_File *common,
447 Eio_Done_Cb done_cb,
448 Eio_Error_Cb error_cb,
449 const void *data,
450 Ecore_Thread_Cb heavy_cb,
451 Ecore_Thread_Notify_Cb notify_cb,
452 Ecore_Thread_Cb end_cb,
453 Ecore_Thread_Cb cancel_cb);
454
455 void eio_file_free(Eio_File *common);
456 void eio_async_free(Eio_File_Ls *async);
457
458 void eio_file_container_set(Eio_File *common, void *container);
459
460 void eio_file_error(Eio_File *common);
461 void eio_file_thread_error(Eio_File *common, Ecore_Thread *thread);
462
463 Eio_File_Direct_Info *eio_direct_info_malloc(void);
464 void eio_direct_info_free(Eio_File_Direct_Info *data);
465
466 Eio_File_Char *eio_char_malloc(void);
467 void eio_char_free(Eio_File_Char *data);
468
469 Eio_File_Associate *eio_associate_malloc(const void *data, Eina_Free_Cb free_cb);
470 void eio_associate_free(void *data);
471
472 Eio_Progress *eio_progress_malloc(void);
473 void eio_progress_free(Eio_Progress *progress);
474
475 void eio_progress_send(Ecore_Thread *thread, Eio_File_Progress *op,
476 long long current, long long max);
477 void eio_progress_cb(Eio_Progress *progress, Eio_File_Progress *op);
478
479 Eina_Bool eio_file_copy_do(Ecore_Thread *thread, Eio_File_Progress *copy);
480
481 void eio_monitor_init(void);
482 void eio_monitor_backend_init(void);
483 void eio_monitor_fallback_init(void);
484
485 void eio_monitor_shutdown(void);
486 void eio_monitor_backend_shutdown(void);
487 void eio_monitor_fallback_shutdown(void);
488 void eio_monitor_backend_add(Eio_Monitor *monitor);
489 Eina_Bool eio_monitor_context_check(const Eio_Monitor *monitor, const char *path);
490 void eio_monitor_fallback_add(Eio_Monitor *monitor);
491 Eina_Bool eio_monitor_fallback_context_check(const Eio_Monitor *monitor, const char *path);
492
493 void eio_monitor_backend_del(Eio_Monitor *monitor);
494 void eio_monitor_fallback_del(Eio_Monitor *monitor);
495
496 void _eio_monitor_send(Eio_Monitor *monitor, const char *filename, int event_code);
497 void _eio_monitor_rename(Eio_Monitor *monitor, const char *newpath);
498
499 void eio_async_end(void *data, Ecore_Thread *thread);
500 void eio_async_error(void *data, Ecore_Thread *thread);
501
502 Eina_List *eio_pack_send(Ecore_Thread *thread, Eina_List *pack, double *start);
503
504 void *eio_common_alloc(size_t size);
505 void eio_common_free(Eio_File *common);
506
507 void eio_file_register(Eio_File *common);
508 void eio_file_unregister(Eio_File *common);
509
510 Eio_File * _eio_file_ls(const char *dir,
511 Eio_Array_Cb main_internal_cb,
512 Eio_Done_Cb done_cb,
513 Eio_Error_Cb error_cb,
514 const void *data);
515 Eio_File * _eio_file_direct_ls(const char *dir,
516 Eio_Array_Cb main_internal_cb,
517 Eio_Done_Cb done_cb,
518 Eio_Error_Cb error_cb,
519 const void *data);
520 Eio_File * _eio_dir_direct_ls(const char *dir,
521 Eio_Array_Cb main_internal_cb,
522 Eio_Done_Cb done_cb,
523 Eio_Error_Cb error_cb,
524 const void *data);
525 Eio_File * _eio_file_stat_ls(const char *dir,
526 Eio_Array_Cb main_internal_cb,
527 Eio_Done_Cb done_cb,
528 Eio_Error_Cb error_cb,
529 const void *data);
530 Eio_File * _eio_dir_stat_ls(const char *dir,
531 Eio_Array_Cb main_internal_cb,
532 Eio_Done_Cb done_cb,
533 Eio_Error_Cb error_cb,
534 const void *data);
535 Eio_File * _eio_file_xattr(const char *path,
536 Eio_Array_Cb main_internal_cb,
537 Eio_Done_Cb done_cb,
538 Eio_Error_Cb error_cb,
539 const void *data);
540
541 // Sharing notifier between recursive and non recursive code.
542 void _eio_string_notify(void *data, Ecore_Thread *thread EINA_UNUSED, void *msg_data);
543 void _eio_direct_notify(void *data, Ecore_Thread *thread EINA_UNUSED, void *msg_data);
544
545 static inline Eina_Value
_efl_io_manager_future_cancel(Eo * o EINA_UNUSED,void * data,Eina_Error error)546 _efl_io_manager_future_cancel(Eo *o EINA_UNUSED, void *data, Eina_Error error)
547 {
548 if (error == ECANCELED) eio_file_cancel(data);
549
550 return eina_value_error_init(error);
551 }
552
553 static inline Eina_Future *
_efl_io_manager_future(const Eo * o,Eina_Future * f,Eio_File * h)554 _efl_io_manager_future(const Eo *o, Eina_Future *f, Eio_File *h)
555 {
556 return efl_future_then(o, f,
557 .error = _efl_io_manager_future_cancel,
558 .data = h);
559 }
560
561 EINA_VALUE_STRUCT_DESC_DEFINE(_eina_stat_desc,
562 NULL,
563 sizeof (Eina_Stat),
564 EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_ULONG, Eina_Stat, dev),
565 EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_ULONG, Eina_Stat, ino),
566 EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_UINT, Eina_Stat, mode),
567 EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_UINT, Eina_Stat, nlink),
568 EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_UINT, Eina_Stat, uid),
569 EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_UINT, Eina_Stat, gid),
570 EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_ULONG, Eina_Stat, rdev),
571 EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_ULONG, Eina_Stat, size),
572 EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_ULONG, Eina_Stat, blksize),
573 EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_ULONG, Eina_Stat, blocks),
574 EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_TIMESTAMP, Eina_Stat, atime),
575 EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_ULONG, Eina_Stat, atimensec),
576 EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_TIMESTAMP, Eina_Stat, mtime),
577 EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_ULONG, Eina_Stat, mtimensec),
578 EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_TIMESTAMP, Eina_Stat, ctime),
579 EINA_VALUE_STRUCT_MEMBER(EINA_VALUE_TYPE_ULONG, Eina_Stat, ctimensec));
580
581 #endif
582