/** \file aft.c Audio file table functions. */
+#include <dirent.h> /* readdir() */
#include "para.h"
#include "error.h"
#include "string.h"
#include "afs.h"
#include "net.h"
#include "vss.h"
+#include "fd.h"
static struct osl_table *audio_file_table;
ret = get_chunk_table_of_row(aft_row, &afd->afhi);
if (ret < 0)
return ret;
- ret = mmap_full_file(afd->path, O_RDONLY, &afd->map);
+ ret = mmap_full_file(afd->path, O_RDONLY, &afd->map.data,
+ &afd->map.size, NULL);
if (ret < 0)
goto err;
hash_function(afd->map.data, afd->map.size, file_hash);
goto out_free;
}
/* We still want to add this file. Compute its hash. */
- ret = mmap_full_file(path, O_RDONLY, &map);
+ ret = mmap_full_file(path, O_RDONLY, &map.data, &map.size, NULL);
if (ret < 0)
goto out_free;
hash_function(map.data, map.size, hash);
PARA_ERROR(STAT, "can not stat file"), \
PARA_ERROR(FSTAT, "fstat error"), \
PARA_ERROR(RENAME, "rename failed"), \
- PARA_ERROR(EMPTY, "file empty"), \
- PARA_ERROR(MMAP, "mmap error"), \
PARA_ERROR(MUNMAP, "munmap failed"), \
PARA_ERROR(WRITE, "write error"), \
PARA_ERROR(LSEEK, "lseek error"), \
PARA_ERROR(CHDIR, "failed to change directory"), \
PARA_ERROR(OPEN, "failed to open file"), \
PARA_ERROR(CHDIR_PERM, "insufficient permissions to chdir"), \
+ PARA_ERROR(EMPTY, "file empty"), \
+ PARA_ERROR(MMAP, "mmap error"), \
#define WRITE_ERRORS \
return 1;
return -ERRNO_TO_PARA_ERROR(errno);
}
+
+/**
+ * Map a file into memory.
+ *
+ * \param path Name of the regular file to map.
+ * \param open_mode Either \p O_RDONLY or \p O_RDWR.
+ * \param obj On success, the mapping is returned here.
+ *
+ * \return Positive on success, negative on errors. Possible errors include: \p
+ * E_FSTAT, any errors returned by para_open(), \p E_EMPTY, \p E_MMAP.
+ *
+ * \sa para_open(), mmap(2).
+ */
+int mmap_full_file(const char *path, int open_mode, void **map,
+ size_t *size, int *fd_ptr)
+{
+ int fd, ret, mmap_prot, mmap_flags;
+ struct stat file_status;
+
+ if (open_mode == O_RDONLY) {
+ mmap_prot = PROT_READ;
+ mmap_flags = MAP_PRIVATE;
+ } else {
+ mmap_prot = PROT_READ | PROT_WRITE;
+ mmap_flags = MAP_SHARED;
+ }
+ ret = para_open(path, open_mode, 0);
+ if (ret < 0)
+ return ret;
+ fd = ret;
+ if (fstat(fd, &file_status) < 0) {
+ ret = -ERRNO_TO_PARA_ERROR(errno);
+ goto out;
+ }
+ *size = file_status.st_size;
+ ret = -E_EMPTY;
+ PARA_DEBUG_LOG("%s: size %zu\n", path, *size);
+ if (!*size)
+ goto out;
+ *map = mmap(NULL, *size, mmap_prot, mmap_flags, fd, 0);
+ if (*map == MAP_FAILED) {
+ *map = NULL;
+ ret = -E_MMAP;
+ goto out;
+ }
+ ret = 1;
+out:
+ if (ret < 0 || !fd_ptr)
+ close(fd);
+ else
+ *fd_ptr = fd;
+ return ret;
+}
int para_mkdir(const char *path, mode_t mode);
int para_fchdir(int fd);
int para_chdir(const char *path);
+int mmap_full_file(const char *filename, int open_mode, void **map,
+ size_t *size, int *fd_ptr);
char *filename = index_filename(desc);
int ret;
- ret = mmap_full_file(filename, O_RDWR, map);
+ ret = mmap_full_file(filename, O_RDWR, &map->data, &map->size, NULL);
PARA_INFO_LOG("mapping index %s: ret: %d, size: %zu\n", filename, ret, map->size);
free(filename);
return ret;
ds_name = disk_storage_name_of_hash(t, hash);
FOR_EACH_DISK_STORAGE_COLUMN(i, t, cd) {
filename = disk_storage_path(t, i, ds_name);
- ret = mmap_full_file(filename, O_RDONLY, &obj);
+ ret = mmap_full_file(filename, O_RDONLY, &obj.data, &obj.size, NULL);
free(filename);
if (ret < 0)
goto out;
return ret;
}
-/**
- * Map a file into memory.
- *
- * \param path Name of the regular file to map.
- * \param open_mode Either \p O_RDONLY or \p O_RDWR.
- * \param obj On success, the mapping is returned here.
- *
- * \return Positive on success, negative on errors. Possible errors include: \p
- * E_FSTAT, any errors returned by para_open(), \p E_EMPTY, \p E_MMAP.
- *
- * \sa para_open(), mmap(2).
- */
-int mmap_full_file(const char *path, int open_mode, struct osl_object *obj)
-{
- int fd, ret, mmap_prot, mmap_flags;
- struct stat file_status;
-
- if (open_mode == O_RDONLY) {
- mmap_prot = PROT_READ;
- mmap_flags = MAP_PRIVATE;
- } else {
- mmap_prot = PROT_READ | PROT_WRITE;
- mmap_flags = MAP_SHARED;
- }
- ret = para_open(path, open_mode, 0);
- if (ret < 0)
- return ret;
- fd = ret;
- ret = -E_FSTAT;
- if (fstat(fd, &file_status) < 0)
- goto out;
- obj->size = file_status.st_size;
- ret = -E_EMPTY;
- PARA_DEBUG_LOG("%s: size %zu\n", path, obj->size);
- if (!obj->size)
- goto out;
- obj->data = mmap(NULL, obj->size, mmap_prot, mmap_flags, fd, 0);
- if (obj->data == MAP_FAILED) {
- obj->data = NULL;
- ret = -E_MMAP;
- goto out;
- }
- ret = 1;
-out:
- close(fd);
- return ret;
-}
-
/**
* Traverse the given directory recursively.
*
return ret;
}
ret = mmap_full_file(filename, O_RDWR,
- &t->columns[col_num].data_map);
+ &t->columns[col_num].data_map.data,
+ &t->columns[col_num].data_map.size,
+ NULL);
free(filename);
return ret;
}
filename = index_filename(t->desc);
PARA_DEBUG_LOG("mapping table '%s' (index: %s)\n", t->desc->name, filename);
ret = mmap_full_file(filename, flags & MAP_TBL_FL_MAP_RDONLY?
- O_RDONLY : O_RDWR, &t->index_map);
+ O_RDONLY : O_RDWR, &t->index_map.data, &t->index_map.size, NULL);
free(filename);
if (ret < 0)
return ret;
filename = disk_storage_path(t, col_num, ds_name);
free(ds_name);
PARA_DEBUG_LOG("filename: %s\n", filename);
- ret = mmap_full_file(filename, O_RDONLY, obj);
+ ret = mmap_full_file(filename, O_RDONLY, &obj->data, &obj->size, NULL);
free(filename);
return ret;
}
int for_each_file_in_dir(const char *dirname,
int (*func)(const char *, const void *), const void *private_data);
-int mmap_full_file(const char *filename, int open_mode, struct osl_object *obj);
ssize_t para_write_all(int fd, const void *buf, size_t size);
int para_lseek(int fd, off_t *offset, int whence);
int para_write_file(const char *filename, const void *buf, size_t size);