diff --git a/src/fileops.c b/src/fileops.c index 16b9dc520..f494e4772 100644 --- a/src/fileops.c +++ b/src/fileops.c @@ -1,5 +1,6 @@ #include "common.h" #include "fileops.h" +#include int gitfo_open(const char *path, int flags) { @@ -106,6 +107,20 @@ void gitfo_free_buf(gitfo_buf *obj) obj->data = NULL; } +int gitfo_map_ro(gitfo_map *out, git_file fd, off_t begin, size_t len) +{ + out->data = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, begin); + if (out->data == (void*)-1) + return git_os_error(); + out->len = len; + return GIT_SUCCESS; +} + +void gitfo_free_map(gitfo_map *out) +{ + munmap(out->data, out->len); +} + /* cached diskio */ struct gitfo_cache { git_file fd; diff --git a/src/fileops.h b/src/fileops.h index 820e02cce..22237f6c0 100644 --- a/src/fileops.h +++ b/src/fileops.h @@ -30,6 +30,10 @@ typedef struct { /* file io buffer */ size_t len; /* data length */ } gitfo_buf; +typedef struct { /* memory mapped buffer */ + void *data; /* data bytes */ + size_t len; /* data length */ +} gitfo_map; extern int gitfo_exists(const char *path); extern int gitfo_open(const char *path, int flags); @@ -43,6 +47,33 @@ extern off_t gitfo_size(git_file fd); extern int gitfo_read_file(gitfo_buf *obj, const char *path); extern void gitfo_free_buf(gitfo_buf *obj); +/** + * Read-only map all or part of a file into memory. + * When possible this function should favor a virtual memory + * style mapping over some form of malloc()+read(), as the + * data access will be random and is not likely to touch the + * majority of the region requested. + * + * @param out buffer to populate with the mapping information. + * @param fd open descriptor to configure the mapping from. + * @param begin first byte to map, this should be page aligned. + * @param end number of bytes to map. + * @return + * - GIT_SUCCESS on success; + * - GIT_EOSERR on an unspecified OS related error. + */ +extern int gitfo_map_ro( + gitfo_map *out, + git_file fd, + off_t begin, + size_t len); + +/** + * Release the memory associated with a previous memory mapping. + * @param map the mapping description previously configured. + */ +extern void gitfo_free_map(gitfo_map *map); + /** * Walk each directory entry, except '.' and '..', calling fn(state). *