summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2019-07-21 15:10:34 +0200
committerPatrick Steinhardt <ps@pks.im>2019-07-21 15:16:34 +0200
commit2766b92de755871b666217912d865c46ed289011 (patch)
tree1f81ac39c55a4bf0d4bb616f59c49184b8930948
parent9fac8b78347b5830bc1068efd804fa25ebc9ec1e (diff)
downloadlibgit2-2766b92de755871b666217912d865c46ed289011.tar.gz
config_file: refresh when creating an iterator
When creating a new iterator for a config file backend, then we should always make sure that we're up to date by calling `config_refresh`. Otherwise, we might not notice when another process has modified the configuration file and thus will represent outdated values. Add two tests to config::stress that verify that we get up-to-date values when reading configuration entries via `git_config_iterator`.
-rw-r--r--src/config_file.c9
-rw-r--r--tests/config/stress.c45
2 files changed, 49 insertions, 5 deletions
diff --git a/src/config_file.c b/src/config_file.c
index 1b674b135..88bba90a7 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -270,13 +270,12 @@ static int config_iterator_new(
struct git_config_backend *backend)
{
diskfile_header *bh = GIT_CONTAINER_OF(backend, diskfile_header, parent);
- git_config_entries *entries;
+ git_config_entries *entries = NULL;
int error;
- if ((error = git_config_entries_dup(&entries, bh->entries)) < 0)
- return error;
-
- if ((error = git_config_entries_iterator_new(iter, entries)) < 0)
+ if ((error = config_refresh(backend)) < 0 ||
+ (error = git_config_entries_dup(&entries, bh->entries)) < 0 ||
+ (error = git_config_entries_iterator_new(iter, entries)) < 0)
goto out;
out:
diff --git a/tests/config/stress.c b/tests/config/stress.c
index 4fb0f3b26..4ee234f17 100644
--- a/tests/config/stress.c
+++ b/tests/config/stress.c
@@ -131,3 +131,48 @@ void test_config_stress__quick_write(void)
git_config_free(config_r);
git_config_free(config_w);
}
+
+static int foreach_cb(const git_config_entry *entry, void *payload)
+{
+ if (!strcmp(entry->name, "key.value")) {
+ *(char **)payload = git__strdup(entry->value);
+ return 0;
+ }
+ return -1;
+}
+
+void test_config_stress__foreach_refreshes(void)
+{
+ git_config *config_w, *config_r;
+ char *value = NULL;
+
+ cl_git_pass(git_config_open_ondisk(&config_w, "./cfg"));
+ cl_git_pass(git_config_open_ondisk(&config_r, "./cfg"));
+
+ cl_git_pass(git_config_set_string(config_w, "key.value", "1"));
+ cl_git_pass(git_config_foreach_match(config_r, "key.value", foreach_cb, &value));
+
+ cl_assert_equal_s(value, "1");
+
+ git_config_free(config_r);
+ git_config_free(config_w);
+ git__free(value);
+}
+
+void test_config_stress__foreach_refreshes_snapshot(void)
+{
+ git_config *config, *snapshot;
+ char *value = NULL;
+
+ cl_git_pass(git_config_open_ondisk(&config, "./cfg"));
+
+ cl_git_pass(git_config_set_string(config, "key.value", "1"));
+ cl_git_pass(git_config_snapshot(&snapshot, config));
+ cl_git_pass(git_config_foreach_match(snapshot, "key.value", foreach_cb, &value));
+
+ cl_assert_equal_s(value, "1");
+
+ git_config_free(snapshot);
+ git_config_free(config);
+ git__free(value);
+}