summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2016-10-27 21:15:59 -0400
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2016-11-05 18:54:27 -0400
commit54ac349445341503b1651c17b21495039d818a82 (patch)
tree7e4c119befbc46043b383db48e15c5578aad5784
parent035fe294b3fdc054151eacc5a75909f2c479300c (diff)
core/load-fragment: modify existing environment instead of copying strv over and over
-rw-r--r--src/basic/env-util.c22
-rw-r--r--src/basic/env-util.h1
-rw-r--r--src/core/load-fragment.c9
3 files changed, 26 insertions, 6 deletions
diff --git a/src/basic/env-util.c b/src/basic/env-util.c
index b74290d6fd..7c69ccdaf9 100644
--- a/src/basic/env-util.c
+++ b/src/basic/env-util.c
@@ -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;
diff --git a/src/basic/env-util.h b/src/basic/env-util.h
index b1fef704c2..8cb0fc2131 100644
--- a/src/basic/env-util.h
+++ b/src/basic/env-util.h
@@ -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_;
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index 455c11a501..75c048a23e 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -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;
}
}