#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
-#include <fcntl.h>
-#include <sys/mman.h>
#define PATH_DELIM '/'
#include "eina_safety_checks.h"
#include "eina_file.h"
#include "eina_stringshare.h"
-#include "eina_hash.h"
/*============================================================================*
* Local *
return &it->iterator;
}
-
-/*
- H : half
- X : done
-
- [ ] nom du fichier pour shm_open
- [ ] stringshare pour le fichier
- [H] flags dans des enum
- [X] fstat pour la taille
- [H] enregistrer dans un cache (hash) les fichiers ouverts
- [ ] garder la liste des map ouvertes et les detruire
- [X] mmap tout le fichier
- [ ] hash pour les blocs mmap
- [ ] taille de mmap : sauvegarder dans Eina_File
- */
-
-#include "eina_log.h"
-
-static Eina_Hash *_eina_file_files = NULL;
-
-/* _eina_file_files = eina_hash_string_small_new(NULL) */
-
-typedef enum
-{
- EINA_FILE_FLAG_READ = 0,
- EINA_FILE_FLAG_WRITE = 1,
- EINA_FILE_FLAG_READ_WRITE = 2,
- EINA_FILE_FLAG_CREATE = 1 << 2,
- EINA_FILE_FLAG_TRUNCATE = 1 << 3
-} Eina_File_Flag;
-
-typedef enum
-{
- EINA_FILE_MODE_READ = 1 << 0,
- EINA_FILE_MODE_WRITE = 1 << 1
-} Eina_File_Mode;
-
-typedef enum
-{
- EINA_FILE_MAP_PROT_EXEC,
- EINA_FILE_MAP_PROT_READ,
- EINA_FILE_MAP_PROT_WRITE,
- EINA_FILE_MAP_PROT_NONE
-} Eina_File_Map_Prot;
-
-typedef enum
-{
- /* No MAP_FIXED, its use is discouraged */
- EINA_FILE_MAP_FLAG_SHARED,
- EINA_FILE_MAP_FLAG_PRIVATE
-} Eina_File_Map_Flag;
-
-typedef struct
-{
- char *filename;
- Eina_File_Flag flag;
- Eina_File_Mode mode;
- int fd;
- off_t file_size;
- off_t map_size;
- void *map_full;
- Eina_Hash *map_blocks;
- Eina_Bool shared : 1;
-} Eina_File;
-
-static int _eina_file_log_dom = -1;
-
-#ifdef ERR
-#undef ERR
-#endif
-#define ERR(...) EINA_LOG_DOM_ERR(_eina_file_log_dom, __VA_ARGS__)
-
-Eina_Bool
-eina_file_init(void)
-{
- _eina_file_log_dom = eina_log_domain_register("eina_file",
- EINA_LOG_COLOR_DEFAULT);
- if (_eina_file_log_dom < 0)
- {
- EINA_LOG_ERR("Could not register log domain: eina_file");
- return EINA_FALSE;
- }
-
- return EINA_TRUE;
-}
-
-Eina_Bool
-eina_file_shutdown(void)
-{
- eina_log_domain_unregister(_eina_file_log_dom);
- _eina_file_log_dom = -1;
- return EINA_TRUE;
-}
-
-EAPI Eina_File *
-eina_file_open(const char *filename, Eina_File_Flag flag, Eina_File_Mode mode, Eina_Bool shared)
-{
- struct stat st;
- Eina_File *file;
- Eina_File *cache;
- int oflag;
- mode_t omode = 0;
-
- if (!filename || !*filename) return NULL;
-
- file = (Eina_File *)calloc(1, sizeof(Eina_File));
- if (!file) return NULL;
-
- if (shared)
- {
- size_t length;
-
- length = strlen(filename) + 1;
- file->filename = (char *)malloc(length + 1);
- if (!file->filename) goto free_file;
- *file->filename = '/';
- memcpy(file->filename + 1, filename, length);
- }
- else
- {
- file->filename = strdup(filename);
- if (!file->filename) goto free_file;
- }
-
- file->flag = flag;
- file->mode = mode;
- file->shared = shared;
- switch (flag)
- {
- case EINA_FILE_FLAG_READ:
- oflag = O_RDONLY;
- break;
- case EINA_FILE_FLAG_WRITE:
- oflag = O_WRONLY;
- break;
- case EINA_FILE_FLAG_READ_WRITE:
- oflag = O_RDWR;
- break;
- default:
- oflag = O_RDONLY;
- break;
- }
-
- if (flag & EINA_FILE_FLAG_CREATE) oflag |= O_CREAT;
- if (flag & EINA_FILE_FLAG_TRUNCATE) oflag |= O_TRUNC;
-
- if (mode & EINA_FILE_MODE_READ) omode |= S_IRUSR;
- if (mode & EINA_FILE_MODE_WRITE) omode |= S_IWUSR;
-
- if (shared)
- {
- file->fd = shm_open(file->filename, oflag, omode);
- if (file->fd == -1)
- goto free_filename;
- }
- else
- {
- file->fd = open(file->filename, oflag, omode);
- if (file->fd == -1)
- goto free_filename;
- }
-
- if (fstat(file->fd, &st) != 0)
- {
- ERR("Could not retrieve file size");
- goto close_file;
- }
-
- file->file_size = st.st_size;
-
- cache = eina_hash_find(_eina_file_files, file->filename);
- if (cache)
- {
- /* faire plus de tests ? */
- if (cache->file_size != file->file_size)
- {
- eina_hash_modify(_eina_file_files, file->filename, file);
- free(cache->filename);
- free(cache);
- }
- else
- return cache;
- }
- else
- eina_hash_add(_eina_file_files, file->filename, file);
-
- return file;
-
- close_file:
- if (shared)
- shm_unlink(file->filename);
- else
- close(file->fd);
- free_filename:
- free(file->filename);
- free_file:
- free(file);
-
- return NULL;
-}
-
-EAPI void
-eina_file_close(Eina_File *file)
-{
- if (!file)
- return;
-
- if (eina_hash_find(_eina_file_files, file->filename))
- eina_hash_del(_eina_file_files, file->filename, file);
-
- if (file->shared)
- {
- if (shm_unlink(file->filename) != 0)
- ERR("Could not unlink %s", file->filename);
- }
- else
- {
- if (close(file->fd) != 0)
- ERR("Could not close %s", file->filename);
- }
-
- free(file->filename);
- free(file);
-}
-
-EAPI void *
-eina_file_map_full(Eina_File *file, Eina_File_Map_Prot prot, Eina_File_Map_Flag flags)
-{
- if (!file || !file->shared)
- return NULL;
-
- if (!file->map_full)
- {
- file->map_size = file->file_size;
- file->map_full = mmap(NULL, file->map_size, prot, flags, file->fd, 0);
- }
-
- return file->map_full;
-}
-
-EAPI Eina_Bool
-eina_file_unmap_full(Eina_File *file)
-{
- if (!file || !file->map_full)
- return EINA_FALSE;
-
- return (munmap(file->map_full, file->map_size) == 0) ? EINA_TRUE : EINA_FALSE;
-}
-
-EAPI void *
-eina_file_map(Eina_File *file, void *start, size_t length, Eina_File_Map_Prot prot, Eina_File_Map_Flag flags, off_t offset)
-{
- if (!file)
- return NULL;
-
- if (length > (size_t)file->file_size)
- {
- ERR("Wrong length");
- return NULL;
- }
-
- file->map_size = length;
-
- return mmap(start, file->map_size, prot, flags, file->fd, offset);
-}
-
-EAPI Eina_Bool
-eina_file_unmap(Eina_File *file, void *start)
-{
- if (!file)
- return EINA_FALSE;
-
- return (munmap(start, file->map_size) == 0) ? EINA_TRUE : EINA_FALSE;
-}
-
/**
* @}
*/