aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/eina/src/lib/eina_file.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/eina/src/lib/eina_file.c232
1 files changed, 144 insertions, 88 deletions
diff --git a/libraries/eina/src/lib/eina_file.c b/libraries/eina/src/lib/eina_file.c
index 0b836b3..c465301 100644
--- a/libraries/eina/src/lib/eina_file.c
+++ b/libraries/eina/src/lib/eina_file.c
@@ -362,41 +362,15 @@ _eina_file_direct_ls_iterator_free(Eina_File_Direct_Iterator *it)
362static Eina_Bool 362static Eina_Bool
363_eina_file_stat_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data) 363_eina_file_stat_ls_iterator_next(Eina_File_Direct_Iterator *it, void **data)
364{ 364{
365 struct stat st; 365 Eina_Stat st;
366 366
367 if (!_eina_file_direct_ls_iterator_next(it, data)) 367 if (!_eina_file_direct_ls_iterator_next(it, data))
368 return EINA_FALSE; 368 return EINA_FALSE;
369 369
370 if (it->info.type == EINA_FILE_UNKNOWN) 370 if (it->info.type == EINA_FILE_UNKNOWN)
371 { 371 {
372#ifdef HAVE_FSTATAT 372 if (eina_file_statat(it->dirp, &it->info, &st) != 0)
373 int fd;
374
375 fd = dirfd(it->dirp);
376 if (fstatat(fd, it->info.path + it->info.name_start, &st, 0))
377#else
378 if (stat(it->info.path, &st))
379#endif
380 it->info.type = EINA_FILE_UNKNOWN; 373 it->info.type = EINA_FILE_UNKNOWN;
381 else
382 {
383 if (S_ISREG(st.st_mode))
384 it->info.type = EINA_FILE_REG;
385 else if (S_ISDIR(st.st_mode))
386 it->info.type = EINA_FILE_DIR;
387 else if (S_ISCHR(st.st_mode))
388 it->info.type = EINA_FILE_CHR;
389 else if (S_ISBLK(st.st_mode))
390 it->info.type = EINA_FILE_BLK;
391 else if (S_ISFIFO(st.st_mode))
392 it->info.type = EINA_FILE_FIFO;
393 else if (S_ISLNK(st.st_mode))
394 it->info.type = EINA_FILE_LNK;
395 else if (S_ISSOCK(st.st_mode))
396 it->info.type = EINA_FILE_SOCK;
397 else
398 it->info.type = EINA_FILE_UNKNOWN;
399 }
400 } 374 }
401 375
402 return EINA_TRUE; 376 return EINA_TRUE;
@@ -593,6 +567,14 @@ _eina_file_escape(const char *path, int *length)
593 return result; 567 return result;
594} 568}
595 569
570/**
571 * @endcond
572 */
573
574/*============================================================================*
575 * Global *
576 *============================================================================*/
577
596Eina_Bool 578Eina_Bool
597eina_file_init(void) 579eina_file_init(void)
598{ 580{
@@ -641,13 +623,60 @@ eina_file_shutdown(void)
641 return EINA_TRUE; 623 return EINA_TRUE;
642} 624}
643 625
644/** 626void
645 * @endcond 627eina_file_mmap_faulty(void *addr, long page_size)
646 */ 628{
629 Eina_File_Map *m;
630 Eina_File *f;
631 Eina_Iterator *itf;
632 Eina_Iterator *itm;
647 633
648/*============================================================================* 634 /* NOTE: I actually don't know if other thread are running, I will try to take the lock.
649 * Global * 635 It may be possible that if other thread are not running and they were in the middle of
650 *============================================================================*/ 636 accessing an Eina_File this lock are still taken and we will result as a deadlock. */
637 eina_lock_take(&_eina_file_lock_cache);
638
639 itf = eina_hash_iterator_data_new(_eina_file_cache);
640 EINA_ITERATOR_FOREACH(itf, f)
641 {
642 Eina_Bool faulty = EINA_FALSE;
643
644 eina_lock_take(&f->lock);
645
646 if (f->global_map)
647 {
648 if ((unsigned char *) addr < (((unsigned char *)f->global_map) + f->length) &&
649 (((unsigned char *) addr) + page_size) >= (unsigned char *) f->global_map)
650 {
651 f->global_faulty = EINA_TRUE;
652 faulty = EINA_TRUE;
653 }
654 }
655
656 if (!faulty)
657 {
658 itm = eina_hash_iterator_data_new(f->map);
659 EINA_ITERATOR_FOREACH(itm, m)
660 {
661 if ((unsigned char *) addr < (((unsigned char *)m->map) + m->length) &&
662 (((unsigned char *) addr) + page_size) >= (unsigned char *) m->map)
663 {
664 m->faulty = EINA_TRUE;
665 faulty = EINA_TRUE;
666 break;
667 }
668 }
669 eina_iterator_free(itm);
670 }
671
672 eina_lock_release(&f->lock);
673
674 if (faulty) break;
675 }
676 eina_iterator_free(itf);
677
678 eina_lock_release(&_eina_file_lock_cache);
679}
651 680
652/*============================================================================* 681/*============================================================================*
653 * API * 682 * API *
@@ -950,7 +979,7 @@ eina_file_open(const char *path, Eina_Bool shared)
950 eina_lock_take(&_eina_file_lock_cache); 979 eina_lock_take(&_eina_file_lock_cache);
951 980
952 file = eina_hash_find(_eina_file_cache, filename); 981 file = eina_hash_find(_eina_file_cache, filename);
953 if ((file) && _eina_file_timestamp_compare(file, &file_stat)) 982 if ((file) && !_eina_file_timestamp_compare(file, &file_stat))
954 { 983 {
955 file->delete_me = EINA_TRUE; 984 file->delete_me = EINA_TRUE;
956 eina_hash_del(_eina_file_cache, file->filename, file); 985 eina_hash_del(_eina_file_cache, file->filename, file);
@@ -1029,7 +1058,7 @@ eina_file_close(Eina_File *file)
1029 1058
1030 eina_hash_del(_eina_file_cache, file->filename, file); 1059 eina_hash_del(_eina_file_cache, file->filename, file);
1031 _eina_file_real_close(file); 1060 _eina_file_real_close(file);
1032 1061
1033 eina_lock_release(&_eina_file_lock_cache); 1062 eina_lock_release(&_eina_file_lock_cache);
1034} 1063}
1035 1064
@@ -1196,7 +1225,7 @@ eina_file_map_free(Eina_File *file, void *map)
1196 unsigned long int key[2]; 1225 unsigned long int key[2];
1197 1226
1198 em = eina_hash_find(file->rmap, &map); 1227 em = eina_hash_find(file->rmap, &map);
1199 if (!em) return ; 1228 if (!em) goto on_exit;
1200 1229
1201 em->refcount--; 1230 em->refcount--;
1202 1231
@@ -1217,17 +1246,25 @@ EAPI Eina_Bool
1217eina_file_map_faulted(Eina_File *file, void *map) 1246eina_file_map_faulted(Eina_File *file, void *map)
1218{ 1247{
1219 Eina_File_Map *em; 1248 Eina_File_Map *em;
1249 Eina_Bool r = EINA_FALSE;
1220 1250
1221 EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE); 1251 EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE);
1222 1252
1223 eina_lock_take(&file->lock); 1253 eina_lock_take(&file->lock);
1224 1254
1225 if (file->global_map == map) return file->global_faulty; 1255 if (file->global_map == map)
1256 {
1257 r = file->global_faulty;
1258 }
1259 else
1260 {
1261 em = eina_hash_find(file->rmap, &map);
1262 if (em) r = em->faulty;
1263 }
1226 1264
1227 em = eina_hash_find(file->rmap, &map); 1265 eina_lock_release(&file->lock);
1228 if (!em) return EINA_FALSE;
1229 1266
1230 return em->faulty; 1267 return r;
1231} 1268}
1232 1269
1233EAPI Eina_Iterator * 1270EAPI Eina_Iterator *
@@ -1246,58 +1283,77 @@ eina_file_xattr_value_get(Eina_File *file)
1246 return eina_xattr_value_fd_ls(file->fd); 1283 return eina_xattr_value_fd_ls(file->fd);
1247} 1284}
1248 1285
1249void 1286EAPI int
1250eina_file_mmap_faulty(void *addr, long page_size) 1287eina_file_statat(void *container, Eina_File_Direct_Info *info, Eina_Stat *st)
1251{ 1288{
1252 Eina_File_Map *m; 1289 struct stat buf;
1253 Eina_File *f; 1290#ifdef HAVE_FSTATAT
1254 Eina_Iterator *itf; 1291 int fd;
1255 Eina_Iterator *itm; 1292#endif
1256 1293
1257 /* NOTE: I actually don't know if other thread are running, I will try to take the lock. 1294 EINA_SAFETY_ON_NULL_RETURN_VAL(info, -1);
1258 It may be possible that if other thread are not running and they were in the middle of 1295 EINA_SAFETY_ON_NULL_RETURN_VAL(st, -1);
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 1296
1262 itf = eina_hash_iterator_data_new(_eina_file_cache); 1297#ifdef HAVE_FSTATAT
1263 EINA_ITERATOR_FOREACH(itf, f) 1298 fd = dirfd((DIR*) container);
1299 if (fstatat(fd, info->path + info->name_start, &buf, 0))
1300#else
1301 (void)container;
1302 if (stat(info->path, &buf))
1303#endif
1264 { 1304 {
1265 Eina_Bool faulty = EINA_FALSE; 1305 if (info->type != EINA_FILE_LNK)
1266 1306 info->type = EINA_FILE_UNKNOWN;
1267 eina_lock_take(&f->lock); 1307 return -1;
1268 1308 }
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 1309
1297 if (faulty) break; 1310 if (info->type == EINA_FILE_UNKNOWN)
1311 {
1312 if (S_ISREG(buf.st_mode))
1313 info->type = EINA_FILE_REG;
1314 else if (S_ISDIR(buf.st_mode))
1315 info->type = EINA_FILE_DIR;
1316 else if (S_ISCHR(buf.st_mode))
1317 info->type = EINA_FILE_CHR;
1318 else if (S_ISBLK(buf.st_mode))
1319 info->type = EINA_FILE_BLK;
1320 else if (S_ISFIFO(buf.st_mode))
1321 info->type = EINA_FILE_FIFO;
1322 else if (S_ISLNK(buf.st_mode))
1323 info->type = EINA_FILE_LNK;
1324 else if (S_ISSOCK(buf.st_mode))
1325 info->type = EINA_FILE_SOCK;
1326 else
1327 info->type = EINA_FILE_UNKNOWN;
1298 } 1328 }
1299 eina_iterator_free(itf);
1300 1329
1301 eina_lock_release(&_eina_file_lock_cache); 1330 st->dev = buf.st_dev;
1331 st->ino = buf.st_ino;
1332 st->mode = buf.st_mode;
1333 st->nlink = buf.st_nlink;
1334 st->uid = buf.st_uid;
1335 st->gid = buf.st_gid;
1336 st->rdev = buf.st_rdev;
1337 st->size = buf.st_size;
1338 st->blksize = buf.st_blksize;
1339 st->blocks = buf.st_blocks;
1340 st->atime = buf.st_atime;
1341 st->mtime = buf.st_mtime;
1342 st->ctime = buf.st_ctime;
1343#ifdef _STAT_VER_LINUX
1344# if (defined __USE_MISC && defined st_mtime)
1345 st->atimensec = buf.st_atim.tv_nsec;
1346 st->mtimensec = buf.st_mtim.tv_nsec;
1347 st->ctimensec = buf.st_ctim.tv_nsec;
1348# else
1349 st->atimensec = buf.st_atimensec;
1350 st->mtimensec = buf.st_mtimensec;
1351 st->ctimensec = buf.st_ctimensec;
1352# endif
1353#else
1354 st->atimensec = 0;
1355 st->mtimensec = 0;
1356 st->ctimensec = 0;
1357#endif
1358 return 0;
1302} 1359}
1303