diff options
Diffstat (limited to 'src/fileops.c')
| -rw-r--r-- | src/fileops.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/src/fileops.c b/src/fileops.c index 2d1915a96..c7fddc623 100644 --- a/src/fileops.c +++ b/src/fileops.c @@ -141,23 +141,40 @@ git_off_t git_futils_filesize(git_file fd) return sb.st_size; } -int git_futils_readbuffer(git_fbuffer *obj, const char *path) +int git_futils_readbuffer_updated(git_fbuffer *obj, const char *path, time_t *mtime, int *updated) { git_file fd; size_t len; - git_off_t size; + struct stat st; unsigned char *buff; assert(obj && path && *path); - if ((fd = p_open(path, O_RDONLY)) < 0) - return git__throw(GIT_ERROR, "Failed to open %s for reading", path); + if (updated != NULL) + *updated = 0; - if (((size = git_futils_filesize(fd)) < 0) || !git__is_sizet(size+1)) { - p_close(fd); + if (p_stat(path, &st) < 0) + return git__throw(GIT_ENOTFOUND, "Failed to stat file %s", path); + + if (S_ISDIR(st.st_mode)) + return git__throw(GIT_ERROR, "Can't read a dir into a buffer"); + + /* + * If we were given a time, we only want to read the file if it + * has been modified. + */ + if (mtime != NULL && *mtime >= st.st_mtime) + return GIT_SUCCESS; + + if (mtime != NULL) + *mtime = st.st_mtime; + if (!git__is_sizet(st.st_size+1)) return git__throw(GIT_ERROR, "Failed to read file `%s`. An error occured while calculating its size", path); - } - len = (size_t) size; + + len = (size_t) st.st_size; + + if ((fd = p_open(path, O_RDONLY)) < 0) + return git__throw(GIT_EOSERR, "Failed to open %s for reading", path); if ((buff = git__malloc(len + 1)) == NULL) { p_close(fd); @@ -173,12 +190,22 @@ int git_futils_readbuffer(git_fbuffer *obj, const char *path) p_close(fd); + if (mtime != NULL) + *mtime = st.st_mtime; + if (updated != NULL) + *updated = 1; + obj->data = buff; obj->len = len; return GIT_SUCCESS; } +int git_futils_readbuffer(git_fbuffer *obj, const char *path) +{ + return git_futils_readbuffer_updated(obj, path, NULL, NULL); +} + void git_futils_freebuffer(git_fbuffer *obj) { assert(obj); |
