diff --git a/src/basic/env-file.c b/src/basic/env-file.c index 3efd77909c6..14925e72e19 100644 --- a/src/basic/env-file.c +++ b/src/basic/env-file.c @@ -414,30 +414,39 @@ static int load_env_file_push_pairs( const char *key, char *value, void *userdata, int *n_pushed) { - char ***m = userdata; + char ***m = ASSERT_PTR(userdata); + bool added = false; int r; r = check_utf8ness_and_warn(filename, line, key, value); if (r < 0) return r; + /* Check if the key is present */ + for (char **t = *m; t && *t; t += 2) + if (streq(t[0], key)) { + if (value) + r = free_and_replace(t[1], value); + else + r = free_and_strdup(t+1, ""); + goto finish; + } + r = strv_extend(m, key); if (r < 0) return -ENOMEM; - if (!value) { - r = strv_extend(m, ""); - if (r < 0) - return -ENOMEM; - } else { + if (value) r = strv_push(m, value); - if (r < 0) - return r; - } + else + r = strv_extend(m, ""); + added = true; + finish: + if (r < 0) + return r; - if (n_pushed) + if (n_pushed && added) (*n_pushed)++; - return 0; } diff --git a/src/test/test-env-file.c b/src/test/test-env-file.c index 886a8e4bc85..461a0f08101 100644 --- a/src/test/test-env-file.c +++ b/src/test/test-env-file.c @@ -9,7 +9,12 @@ #include "tests.h" #include "tmpfile-util.h" +/* In case of repeating keys, later entries win. */ + #define env_file_1 \ + "a=a\n" \ + "a=b\n" \ + "a=b\n" \ "a=a\n" \ "b=b\\\n" \ "c\n" \ diff --git a/src/test/test-os-util.c b/src/test/test-os-util.c index 5f82748783f..d6336c53e9d 100644 --- a/src/test/test-os-util.c +++ b/src/test/test-os-util.c @@ -67,8 +67,7 @@ TEST(load_os_release_pairs) { _cleanup_strv_free_ char **pairs = NULL; assert_se(load_os_release_pairs(NULL, &pairs) == 0); - assert_se(strv_equal(pairs, STRV_MAKE("ID", "ignored", // FIXME - "ID", "the-id", + assert_se(strv_equal(pairs, STRV_MAKE("ID", "the-id", "NAME", "the-name"))); assert_se(unsetenv("SYSTEMD_OS_RELEASE") == 0);