core/load-fragment: modify existing environment instead of copying strv over and...
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 28 Oct 2016 01:15:59 +0000 (21:15 -0400)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sat, 5 Nov 2016 22:54:27 +0000 (18:54 -0400)
src/basic/env-util.c
src/basic/env-util.h
src/core/load-fragment.c

index b74290d..7c69ccd 100644 (file)
@@ -384,6 +384,28 @@ char **strv_env_unset_many(char **l, ...) {
         return l;
 }
 
+int strv_env_replace(char ***l, char *p) {
+        char **f;
+
+        assert(p);
+
+        /* Replace first occurrence of the env var or add a new one in the
+         * string list. Drop other occurences. Edits in-place. Does not copy p.
+         */
+
+        for (f = *l; f && *f; f++)
+                if (env_match(*f, p)) {
+                        free_and_replace(*f, p);
+                        strv_env_unset(f + 1, p);
+                        return 0;
+                }
+
+        /* We didn't find a match, we need to append p or create a new strv */
+        if (strv_push(l, p) < 0)
+                return -ENOMEM;
+        return 1;
+}
+
 char **strv_env_set(char **x, const char *p) {
 
         char **k, **r;
index b1fef70..8cb0fc2 100644 (file)
@@ -44,6 +44,7 @@ char **strv_env_delete(char **x, unsigned n_lists, ...); /* New copy */
 char **strv_env_set(char **x, const char *p); /* New copy ... */
 char **strv_env_unset(char **l, const char *p); /* In place ... */
 char **strv_env_unset_many(char **l, ...) _sentinel_;
+int strv_env_replace(char ***l, char *p); /* In place ... */
 
 char *strv_env_get_n(char **l, const char *name, size_t k) _pure_;
 char *strv_env_get(char **x, const char *n) _pure_;
index 455c11a..75c048a 100644 (file)
@@ -2240,7 +2240,6 @@ int config_parse_environ(const char *unit,
 
         for (p = rvalue;; ) {
                 _cleanup_free_ char *word = NULL, *k = NULL;
-                char **x;
 
                 r = extract_first_word(&p, &word, NULL, EXTRACT_CUNESCAPE|EXTRACT_QUOTES);
                 if (r == 0)
@@ -2271,12 +2270,10 @@ int config_parse_environ(const char *unit,
                         continue;
                 }
 
-                x = strv_env_set(*env, k);
-                if (!x)
+                r = strv_env_replace(env, k);
+                if (r < 0)
                         return log_oom();
-
-                strv_free(*env);
-                *env = x;
+                k = NULL;
         }
 }