summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@microsoft.com>2015-04-27 15:38:44 -0400
committerEdward Thomson <ethomson@edwardthomson.com>2015-05-04 07:41:37 -0500
commit9c26de0fd175c2fbb9c67908a0f8bcd37e81252b (patch)
tree18cfada9658861fe956843cf3a934ecb29e3666d
parent5a70df94364f5ca7cbf6db2a881b291b8476c4bf (diff)
downloadlibgit2-9c26de0fd175c2fbb9c67908a0f8bcd37e81252b.tar.gz
config: lock the file for write before reading
When writing a configuration file, we want to take a lock on the new file (eg, `config.lock`) before opening the configuration file (`config`) for reading so that we can prevent somebody from changing the contents underneath us.
-rw-r--r--src/config_file.c15
1 files changed, 7 insertions, 8 deletions
diff --git a/src/config_file.c b/src/config_file.c
index c6c9ef5e2..713183a96 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -1789,7 +1789,12 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p
struct reader *reader = git_array_get(cfg->readers, 0);
struct write_data write_data;
- /* TODO: take the lock before reading */
+ /* Lock the file */
+ if ((result = git_filebuf_open(
+ &file, cfg->file_path, 0, GIT_CONFIG_FILE_MODE)) < 0) {
+ git_buf_free(&reader->buffer);
+ return result;
+ }
/* We need to read in our own config file */
result = git_futils_readbuffer(&reader->buffer, cfg->file_path);
@@ -1805,16 +1810,10 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p
reader->eof = 0;
data_start = reader->read_ptr;
} else {
+ git_filebuf_cleanup(&file);
return -1; /* OS error when reading the file */
}
- /* Lock the file */
- if ((result = git_filebuf_open(
- &file, cfg->file_path, 0, GIT_CONFIG_FILE_MODE)) < 0) {
- git_buf_free(&reader->buffer);
- return result;
- }
-
ldot = strrchr(key, '.');
name = ldot + 1;
section = git__strndup(key, ldot - key);