aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/eina/src/lib/eina_file.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/eina/src/lib/eina_file.c')
-rw-r--r--libraries/eina/src/lib/eina_file.c128
1 files changed, 122 insertions, 6 deletions
diff --git a/libraries/eina/src/lib/eina_file.c b/libraries/eina/src/lib/eina_file.c
index 84b9e78..0b836b3 100644
--- a/libraries/eina/src/lib/eina_file.c
+++ b/libraries/eina/src/lib/eina_file.c
@@ -38,13 +38,18 @@ extern "C"
38void *alloca (size_t); 38void *alloca (size_t);
39#endif 39#endif
40 40
41#include <stdlib.h>
41#include <string.h> 42#include <string.h>
42#include <stddef.h> 43#include <stddef.h>
43#include <dirent.h> 44#ifdef HAVE_DIRENT_H
45# include <dirent.h>
46#endif
44#include <sys/types.h> 47#include <sys/types.h>
45#include <sys/stat.h> 48#include <sys/stat.h>
46#include <unistd.h> 49#include <unistd.h>
47#include <sys/mman.h> 50#ifdef HAVE_SYS_MMAN_H
51# include <sys/mman.h>
52#endif
48#include <fcntl.h> 53#include <fcntl.h>
49 54
50#define PATH_DELIM '/' 55#define PATH_DELIM '/'
@@ -60,6 +65,8 @@ void *alloca (size_t);
60#include "eina_list.h" 65#include "eina_list.h"
61#include "eina_lock.h" 66#include "eina_lock.h"
62#include "eina_mmap.h" 67#include "eina_mmap.h"
68#include "eina_log.h"
69#include "eina_xattr.h"
63 70
64#ifdef HAVE_ESCAPE_H 71#ifdef HAVE_ESCAPE_H
65# include <Escape.h> 72# include <Escape.h>
@@ -95,9 +102,8 @@ void *alloca (size_t);
95#define EINA_SMALL_PAGE 4096 102#define EINA_SMALL_PAGE 4096
96# define EINA_HUGE_PAGE 16 * 1024 * 1024 103# define EINA_HUGE_PAGE 16 * 1024 * 1024
97 104
105#ifdef HAVE_DIRENT_H
98typedef struct _Eina_File_Iterator Eina_File_Iterator; 106typedef struct _Eina_File_Iterator Eina_File_Iterator;
99typedef struct _Eina_File_Map Eina_File_Map;
100
101struct _Eina_File_Iterator 107struct _Eina_File_Iterator
102{ 108{
103 Eina_Iterator iterator; 109 Eina_Iterator iterator;
@@ -107,6 +113,7 @@ struct _Eina_File_Iterator
107 113
108 char dir[1]; 114 char dir[1];
109}; 115};
116#endif
110 117
111struct _Eina_File 118struct _Eina_File
112{ 119{
@@ -132,8 +139,10 @@ struct _Eina_File
132 139
133 Eina_Bool shared : 1; 140 Eina_Bool shared : 1;
134 Eina_Bool delete_me : 1; 141 Eina_Bool delete_me : 1;
142 Eina_Bool global_faulty : 1;
135}; 143};
136 144
145typedef struct _Eina_File_Map Eina_File_Map;
137struct _Eina_File_Map 146struct _Eina_File_Map
138{ 147{
139 void *map; 148 void *map;
@@ -144,6 +153,7 @@ struct _Eina_File_Map
144 int refcount; 153 int refcount;
145 154
146 Eina_Bool hugetlb : 1; 155 Eina_Bool hugetlb : 1;
156 Eina_Bool faulty : 1;
147}; 157};
148 158
149static Eina_Hash *_eina_file_cache = NULL; 159static Eina_Hash *_eina_file_cache = NULL;
@@ -156,6 +166,7 @@ static int _eina_file_log_dom = -1;
156 * The code and description of the issue can be found at : 166 * The code and description of the issue can be found at :
157 * http://womble.decadent.org.uk/readdir_r-advisory.html 167 * http://womble.decadent.org.uk/readdir_r-advisory.html
158 */ 168 */
169#ifdef HAVE_DIRENT_H
159static long 170static long
160_eina_name_max(DIR *dirp) 171_eina_name_max(DIR *dirp)
161{ 172{
@@ -390,6 +401,7 @@ _eina_file_stat_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data)
390 401
391 return EINA_TRUE; 402 return EINA_TRUE;
392} 403}
404#endif
393 405
394static void 406static void
395_eina_file_real_close(Eina_File *file) 407_eina_file_real_close(Eina_File *file)
@@ -511,8 +523,8 @@ slprintf(char *str, size_t size, const char *format, ...)
511 va_end(ap); 523 va_end(ap);
512} 524}
513 525
514static char* 526static char *
515_eina_file_escape(const char* path, int* length) 527_eina_file_escape(const char *path, int *length)
516{ 528{
517 char *result = strdup(path ? path : ""); 529 char *result = strdup(path ? path : "");
518 char *p = result; 530 char *p = result;
@@ -738,6 +750,7 @@ eina_file_split(char *path)
738EAPI Eina_Iterator * 750EAPI Eina_Iterator *
739eina_file_ls(const char *dir) 751eina_file_ls(const char *dir)
740{ 752{
753#ifdef HAVE_DIRENT_H
741 Eina_File_Iterator *it; 754 Eina_File_Iterator *it;
742 size_t length; 755 size_t length;
743 756
@@ -773,11 +786,16 @@ eina_file_ls(const char *dir)
773 it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_ls_iterator_free); 786 it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_ls_iterator_free);
774 787
775 return &it->iterator; 788 return &it->iterator;
789#else
790 (void) dir;
791 return NULL;
792#endif
776} 793}
777 794
778EAPI Eina_Iterator * 795EAPI Eina_Iterator *
779eina_file_direct_ls(const char *dir) 796eina_file_direct_ls(const char *dir)
780{ 797{
798#ifdef HAVE_DIRENT_H
781 Eina_File_Direct_Iterator *it; 799 Eina_File_Direct_Iterator *it;
782 size_t length; 800 size_t length;
783 801
@@ -825,11 +843,16 @@ eina_file_direct_ls(const char *dir)
825 it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_direct_ls_iterator_free); 843 it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_direct_ls_iterator_free);
826 844
827 return &it->iterator; 845 return &it->iterator;
846#else
847 (void) dir;
848 return NULL;
849#endif
828} 850}
829 851
830EAPI Eina_Iterator * 852EAPI Eina_Iterator *
831eina_file_stat_ls(const char *dir) 853eina_file_stat_ls(const char *dir)
832{ 854{
855#ifdef HAVE_DIRENT_H
833 Eina_File_Direct_Iterator *it; 856 Eina_File_Direct_Iterator *it;
834 size_t length; 857 size_t length;
835 858
@@ -877,6 +900,10 @@ eina_file_stat_ls(const char *dir)
877 it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_direct_ls_iterator_free); 900 it->iterator.free = FUNC_ITERATOR_FREE(_eina_file_direct_ls_iterator_free);
878 901
879 return &it->iterator; 902 return &it->iterator;
903#else
904 (void) dir;
905 return NULL;
906#endif
880} 907}
881 908
882EAPI Eina_File * 909EAPI Eina_File *
@@ -887,7 +914,9 @@ eina_file_open(const char *path, Eina_Bool shared)
887 char *filename; 914 char *filename;
888 struct stat file_stat; 915 struct stat file_stat;
889 int fd = -1; 916 int fd = -1;
917#ifdef HAVE_EXECVP
890 int flags; 918 int flags;
919#endif
891 920
892 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL); 921 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
893 922
@@ -1184,4 +1213,91 @@ eina_file_map_free(Eina_File *file, void *map)
1184 eina_lock_release(&file->lock); 1213 eina_lock_release(&file->lock);
1185} 1214}
1186 1215
1216EAPI Eina_Bool
1217eina_file_map_faulted(Eina_File *file, void *map)
1218{
1219 Eina_File_Map *em;
1220
1221 EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE);
1222
1223 eina_lock_take(&file->lock);
1224
1225 if (file->global_map == map) return file->global_faulty;
1226
1227 em = eina_hash_find(file->rmap, &map);
1228 if (!em) return EINA_FALSE;
1229
1230 return em->faulty;
1231}
1232
1233EAPI Eina_Iterator *
1234eina_file_xattr_get(Eina_File *file)
1235{
1236 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
1237
1238 return eina_xattr_fd_ls(file->fd);
1239}
1240
1241EAPI Eina_Iterator *
1242eina_file_xattr_value_get(Eina_File *file)
1243{
1244 EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
1245
1246 return eina_xattr_value_fd_ls(file->fd);
1247}
1248
1249void
1250eina_file_mmap_faulty(void *addr, long page_size)
1251{
1252 Eina_File_Map *m;
1253 Eina_File *f;
1254 Eina_Iterator *itf;
1255 Eina_Iterator *itm;
1256
1257 /* NOTE: I actually don't know if other thread are running, I will try to take the lock.
1258 It may be possible that if other thread are not running and they were in the middle of
1259 accessing an Eina_File this lock are still taken and we will result as a deadlock. */
1260 eina_lock_take(&_eina_file_lock_cache);
1261
1262 itf = eina_hash_iterator_data_new(_eina_file_cache);
1263 EINA_ITERATOR_FOREACH(itf, f)
1264 {
1265 Eina_Bool faulty = EINA_FALSE;
1266
1267 eina_lock_take(&f->lock);
1268
1269 if (f->global_map)
1270 {
1271 if ((unsigned char *) addr < (((unsigned char *)f->global_map) + f->length) &&
1272 (((unsigned char *) addr) + page_size) >= (unsigned char *) f->global_map)
1273 {
1274 f->global_faulty = EINA_TRUE;
1275 faulty = EINA_TRUE;
1276 }
1277 }
1278
1279 if (!faulty)
1280 {
1281 itm = eina_hash_iterator_data_new(f->map);
1282 EINA_ITERATOR_FOREACH(itm, m)
1283 {
1284 if ((unsigned char *) addr < (((unsigned char *)m->map) + m->length) &&
1285 (((unsigned char *) addr) + page_size) >= (unsigned char *) m->map)
1286 {
1287 m->faulty = EINA_TRUE;
1288 faulty = EINA_TRUE;
1289 break;
1290 }
1291 }
1292 eina_iterator_free(itm);
1293 }
1294
1295 eina_lock_release(&f->lock);
1296
1297 if (faulty) break;
1298 }
1299 eina_iterator_free(itf);
1300
1301 eina_lock_release(&_eina_file_lock_cache);
1302}
1187 1303