From aaf057c4bbc6055040d7d2c1ec3655ff89249ebd Mon Sep 17 00:00:00 2001 From: =?utf8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 15 Feb 2021 14:09:30 +0100 Subject: [PATCH] basic/env-util: add variant of strv_env_replace() that does strdup internally --- src/basic/env-util.c | 22 +++++++++++++++++++--- src/basic/env-util.h | 1 + src/core/manager.c | 12 ++---------- src/home/homectl.c | 15 ++++++++------- src/nspawn/nspawn.c | 10 +++------- src/shared/user-record.c | 12 ++---------- 6 files changed, 35 insertions(+), 37 deletions(-) diff --git a/src/basic/env-util.c b/src/basic/env-util.c index a75186015e3..5335c6784db 100644 --- a/src/basic/env-util.c +++ b/src/basic/env-util.c @@ -370,9 +370,8 @@ int strv_env_replace(char ***l, char *p) { assert(p); - /* Replace first occurrence of the env var or add a new one in the string list. Drop other occurrences. Edits - * in-place. Does not copy p. p must be a valid key=value assignment. - */ + /* Replace first occurrence of the env var or add a new one in the string list. Drop other + * occurrences. Edits in-place. Does not copy p. p must be a valid key=value assignment. */ t = strchr(p, '='); if (!t) @@ -395,6 +394,23 @@ int strv_env_replace(char ***l, char *p) { return 1; } +int strv_env_replace_strdup(char ***l, const char *assignment) { + int r; + + /* Like strv_env_replace(), but copies the argument. */ + + _cleanup_free_ char *p = strdup(assignment); + if (!p) + return -ENOMEM; + + r = strv_env_replace(l, p); + if (r < 0) + return r; + + TAKE_PTR(p); + return r; +} + char **strv_env_set(char **x, const char *p) { _cleanup_strv_free_ char **ret = NULL; size_t n, m; diff --git a/src/basic/env-util.h b/src/basic/env-util.h index 5d8afec0289..922cfe1c44a 100644 --- a/src/basic/env-util.h +++ b/src/basic/env-util.h @@ -46,6 +46,7 @@ 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 ... */ +int strv_env_replace_strdup(char ***l, const char *assignment); char *strv_env_get_n(char **l, const char *name, size_t k, unsigned flags) _pure_; char *strv_env_get(char **x, const char *n) _pure_; diff --git a/src/core/manager.c b/src/core/manager.c index 0a7a4518356..377c0b1ccc0 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -641,22 +641,14 @@ int manager_default_environment(Manager *m) { /* Import locale variables LC_*= from configuration */ (void) locale_setup(&m->transient_environment); } else { - _cleanup_free_ char *k = NULL; - - /* The user manager passes its own environment - * along to its children, except for $PATH. */ + /* The user manager passes its own environment along to its children, except for $PATH. */ m->transient_environment = strv_copy(environ); if (!m->transient_environment) return log_oom(); - k = strdup("PATH=" DEFAULT_USER_PATH); - if (!k) - return log_oom(); - - r = strv_env_replace(&m->transient_environment, k); + r = strv_env_replace_strdup(&m->transient_environment, "PATH=" DEFAULT_USER_PATH); if (r < 0) return log_oom(); - TAKE_PTR(k); } sanitize_environment(m->transient_environment); diff --git a/src/home/homectl.c b/src/home/homectl.c index bf35fa03f0d..dfbd12a4dfd 100644 --- a/src/home/homectl.c +++ b/src/home/homectl.c @@ -2511,7 +2511,7 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_SETENV: { - _cleanup_free_ char **l = NULL, **k = NULL; + _cleanup_free_ char **l = NULL; _cleanup_(json_variant_unrefp) JsonVariant *ne = NULL; JsonVariant *e; @@ -2524,7 +2524,8 @@ static int parse_argv(int argc, char *argv[]) { } if (!env_assignment_is_valid(optarg)) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Environment assignment '%s' not valid.", optarg); + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Environment assignment '%s' not valid.", optarg); e = json_variant_by_key(arg_identity_extra, "environment"); if (e) { @@ -2533,13 +2534,13 @@ static int parse_argv(int argc, char *argv[]) { return log_error_errno(r, "Failed to parse JSON environment field: %m"); } - k = strv_env_set(l, optarg); - if (!k) - return log_oom(); + r = strv_env_replace_strdup(&l, optarg); + if (r < 0) + return log_error_errno(r, "Failed to replace JSON environment field: %m"); - strv_sort(k); + strv_sort(l); - r = json_variant_new_array_strv(&ne, k); + r = json_variant_new_array_strv(&ne, l); if (r < 0) return log_error_errno(r, "Failed to allocate environment list JSON: %m"); diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index e1c55d05427..28c51fc76f4 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1109,17 +1109,13 @@ static int parse_argv(int argc, char *argv[]) { break; case 'E': { - char **n; - if (!env_assignment_is_valid(optarg)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Environment variable assignment '%s' is not valid.", optarg); + r = strv_env_replace_strdup(&arg_setenv, optarg); + if (r < 0) + return r; - n = strv_env_set(arg_setenv, optarg); - if (!n) - return log_oom(); - - strv_free_and_replace(arg_setenv, n); arg_settings_mask |= SETTING_ENVIRONMENT; break; } diff --git a/src/shared/user-record.c b/src/shared/user-record.c index 0b07e4427ee..569102f5f27 100644 --- a/src/shared/user-record.c +++ b/src/shared/user-record.c @@ -620,7 +620,6 @@ static int json_dispatch_environment(const char *name, JsonVariant *variant, Jso return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an array.", strna(name)); for (i = 0; i < json_variant_elements(variant); i++) { - _cleanup_free_ char *c = NULL; JsonVariant *e; const char *a; @@ -633,19 +632,12 @@ static int json_dispatch_environment(const char *name, JsonVariant *variant, Jso if (!env_assignment_is_valid(a)) return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an array of environment variables.", strna(name)); - c = strdup(a); - if (!c) - return json_log_oom(variant, flags); - - r = strv_env_replace(&n, c); + r = strv_env_replace_strdup(&n, a); if (r < 0) return json_log_oom(variant, flags); - - c = NULL; } - strv_free_and_replace(*l, n); - return 0; + return strv_free_and_replace(*l, n); } int json_dispatch_user_disposition(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) { -- 2.47.3