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