diff options
author | Russell Belfer <rb@github.com> | 2012-10-30 12:10:36 -0700 |
---|---|---|
committer | Russell Belfer <rb@github.com> | 2012-10-30 12:11:23 -0700 |
commit | 744cc03e2b6d77712bfcb504c272d2e646da650c (patch) | |
tree | 6dd5c8cf23e02cf4a5b96800e19dc9749d08cc75 /src/fileops.c | |
parent | efde422553e1181933d0bc9d7112740e858a847b (diff) | |
download | libgit2-744cc03e2b6d77712bfcb504c272d2e646da650c.tar.gz |
Add git_config_refresh() API to reload config
This adds a new API that allows users to reload the config if the
file has changed on disk. A new config callback function to
refresh the config was added.
The modified time and file size are used to test if the file needs
to be reloaded (and are now stored in the disk backend object).
In writing tests, just using mtime was a problem / race, so I
wanted to check file size as well. To support that, I extended
`git_futils_readbuffer_updated` to optionally check file size in
addition to mtime, and I added a new function `git_filebuf_stats`
to fetch the mtime and size for an open filebuf (so that the
config could be easily refreshed after a write).
Lastly, I moved some similar file checking code for attributes
into filebuf. It is still only being used for attrs, but it
seems potentially reusable, so I thought I'd move it over.
Diffstat (limited to 'src/fileops.c')
-rw-r--r-- | src/fileops.c | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/src/fileops.c b/src/fileops.c index 6342b1679..c22622c72 100644 --- a/src/fileops.c +++ b/src/fileops.c @@ -142,10 +142,11 @@ int git_futils_readbuffer_fd(git_buf *buf, git_file fd, size_t len) } int git_futils_readbuffer_updated( - git_buf *buf, const char *path, time_t *mtime, int *updated) + git_buf *buf, const char *path, time_t *mtime, size_t *size, int *updated) { git_file fd; struct stat st; + bool changed = false; assert(buf && path && *path); @@ -162,16 +163,25 @@ int git_futils_readbuffer_updated( } /* - * If we were given a time, we only want to read the file if it - * has been modified. + * If we were given a time and/or a size, we only want to read the file + * if it has been modified. */ - if (mtime != NULL && *mtime >= st.st_mtime) { + if (size && *size != (size_t)st.st_size) + changed = true; + if (mtime && *mtime != st.st_mtime) + changed = true; + if (!size && !mtime) + changed = true; + + if (!changed) { p_close(fd); return 0; } if (mtime != NULL) *mtime = st.st_mtime; + if (size != NULL) + *size = (size_t)st.st_size; if (git_futils_readbuffer_fd(buf, fd, (size_t)st.st_size) < 0) { p_close(fd); @@ -188,7 +198,7 @@ int git_futils_readbuffer_updated( int git_futils_readbuffer(git_buf *buf, const char *path) { - return git_futils_readbuffer_updated(buf, path, NULL, NULL); + return git_futils_readbuffer_updated(buf, path, NULL, NULL, NULL); } int git_futils_mv_withpath(const char *from, const char *to, const mode_t dirmode) @@ -660,3 +670,28 @@ int git_futils_cp_r( return error; } + +int git_futils_stat_sig_needs_reload( + git_futils_stat_sig *sig, const char *path) +{ + struct stat st; + + /* if the sig is NULL, then alway reload */ + if (sig == NULL) + return 1; + + if (p_stat(path, &st) < 0) + return GIT_ENOTFOUND; + + if ((git_time_t)st.st_mtime == sig->seconds && + (git_off_t)st.st_size == sig->size && + (unsigned int)st.st_ino == sig->ino) + return 0; + + sig->seconds = (git_time_t)st.st_mtime; + sig->size = (git_off_t)st.st_size; + sig->ino = (unsigned int)st.st_ino; + + return 1; +} + |