From 4ab3d29ff03c0508f47846875d9310cbc5b8cd0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 7 Aug 2021 10:16:19 +0200 Subject: [PATCH] Add implicit sentinel to strv_env_merge() Just to make it a tiny bit nicer to use. --- src/basic/env-util.c | 40 ++++++++++++++++++++++++++-------------- src/basic/env-util.h | 3 ++- src/core/dbus-execute.c | 4 ++-- src/core/execute.c | 5 ++--- src/core/locale-setup.c | 2 +- src/core/manager.c | 6 +++--- src/core/service.c | 2 +- src/notify/notify.c | 2 +- src/nspawn/nspawn.c | 20 ++++++++++---------- src/run/run.c | 2 +- src/test/test-env-util.c | 2 +- 11 files changed, 50 insertions(+), 38 deletions(-) diff --git a/src/basic/env-util.c b/src/basic/env-util.c index 81b1e3f10e5..0c30ddc2775 100644 --- a/src/basic/env-util.c +++ b/src/basic/env-util.c @@ -183,39 +183,51 @@ static int env_append(char **r, char ***k, char **a) { return 0; } -char **strv_env_merge(size_t n_lists, ...) { - _cleanup_strv_free_ char **ret = NULL; - size_t n = 0; - char **l, **k; +char** _strv_env_merge(char **first, ...) { + _cleanup_strv_free_ char **merged = NULL; + char **k; va_list ap; /* Merges an arbitrary number of environment sets */ - va_start(ap, n_lists); - for (size_t i = 0; i < n_lists; i++) { + size_t n = strv_length(first); + + va_start(ap, first); + for (;;) { + char **l; + l = va_arg(ap, char**); + if (l == POINTER_MAX) + break; + n += strv_length(l); } va_end(ap); - ret = new(char*, n+1); - if (!ret) + k = merged = new(char*, n + 1); + if (!merged) + return NULL; + merged[0] = NULL; + + if (env_append(merged, &k, first) < 0) return NULL; - *ret = NULL; - k = ret; + va_start(ap, first); + for (;;) { + char **l; - va_start(ap, n_lists); - for (size_t i = 0; i < n_lists; i++) { l = va_arg(ap, char**); - if (env_append(ret, &k, l) < 0) { + if (l == POINTER_MAX) + break; + + if (env_append(merged, &k, l) < 0) { va_end(ap); return NULL; } } va_end(ap); - return TAKE_PTR(ret); + return TAKE_PTR(merged); } static bool env_match(const char *t, const char *pattern) { diff --git a/src/basic/env-util.h b/src/basic/env-util.h index 1fbe7e42709..18d10ebab8f 100644 --- a/src/basic/env-util.h +++ b/src/basic/env-util.h @@ -39,7 +39,8 @@ char **strv_env_clean_with_callback(char **l, void (*invalid_callback)(const cha bool strv_env_name_is_valid(char **l); bool strv_env_name_or_assignment_is_valid(char **l); -char **strv_env_merge(size_t n_lists, ...); +char** _strv_env_merge(char **first, ...); +#define strv_env_merge(first, ...) _strv_env_merge(first, __VA_ARGS__, POINTER_MAX) char **strv_env_delete(char **x, size_t n_lists, ...); /* New copy */ char **strv_env_unset(char **l, const char *p); /* In place ... */ diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index f6783e924ab..5ea97b91940 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -2888,7 +2888,7 @@ int bus_exec_context_set_transient_property( if (!joined) return -ENOMEM; - e = strv_env_merge(2, c->environment, l); + e = strv_env_merge(c->environment, l); if (!e) return -ENOMEM; @@ -2922,7 +2922,7 @@ int bus_exec_context_set_transient_property( if (!joined) return -ENOMEM; - e = strv_env_merge(2, c->unset_environment, l); + e = strv_env_merge(c->unset_environment, l); if (!e) return -ENOMEM; diff --git a/src/core/execute.c b/src/core/execute.c index 46089562590..5bee44ac7b5 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -4158,8 +4158,7 @@ static int exec_child( return log_oom(); } - accum_env = strv_env_merge(5, - params->environment, + accum_env = strv_env_merge(params->environment, our_env, pass_env, context->environment, @@ -5214,7 +5213,7 @@ static int exec_context_load_environment(const Unit *unit, const ExecContext *c, else { char **m; - m = strv_env_merge(2, r, p); + m = strv_env_merge(r, p); strv_free(r); strv_free(p); if (!m) diff --git a/src/core/locale-setup.c b/src/core/locale-setup.c index 64761ddb118..59ddb9c4875 100644 --- a/src/core/locale-setup.c +++ b/src/core/locale-setup.c @@ -85,7 +85,7 @@ int locale_setup(char ***environment) { else { char **merged; - merged = strv_env_merge(2, *environment, add); + merged = strv_env_merge(*environment, add); if (!merged) return -ENOMEM; diff --git a/src/core/manager.c b/src/core/manager.c index 24dfe9fc06b..d76b7b2b16c 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -3672,7 +3672,7 @@ int manager_transient_environment_add(Manager *m, char **plus) { if (strv_isempty(plus)) return 0; - a = strv_env_merge(2, m->transient_environment, plus); + a = strv_env_merge(m->transient_environment, plus); if (!a) return log_oom(); @@ -3704,7 +3704,7 @@ int manager_client_environment_modify( } if (!strv_isempty(plus)) { - b = strv_env_merge(2, l, plus); + b = strv_env_merge(l, plus); if (!b) { strv_free(a); return -ENOMEM; @@ -3731,7 +3731,7 @@ int manager_get_effective_environment(Manager *m, char ***ret) { assert(m); assert(ret); - l = strv_env_merge(2, m->transient_environment, m->client_environment); + l = strv_env_merge(m->transient_environment, m->client_environment); if (!l) return -ENOMEM; diff --git a/src/core/service.c b/src/core/service.c index ddcfeb8523f..4115db0a302 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1546,7 +1546,7 @@ static int service_spawn( if (r < 0) return r; - final_env = strv_env_merge(2, exec_params.environment, our_env, NULL); + final_env = strv_env_merge(exec_params.environment, our_env); if (!final_env) return -ENOMEM; diff --git a/src/notify/notify.c b/src/notify/notify.c index 49d5f3ec92a..b468a5bc448 100644 --- a/src/notify/notify.c +++ b/src/notify/notify.c @@ -232,7 +232,7 @@ static int run(int argc, char* argv[]) { our_env[i++] = NULL; - final_env = strv_env_merge(2, our_env, argv + optind); + final_env = strv_env_merge(our_env, argv + optind); if (!final_env) return log_oom(); diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index d75cce408e7..cf89b27dfa8 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -3189,8 +3189,8 @@ static int inner_child( _cleanup_free_ char *home = NULL; char as_uuid[ID128_UUID_STRING_MAX]; size_t n_env = 1; - const char *envp[] = { - "PATH=" DEFAULT_PATH_COMPAT, + char *envp[] = { + (char*) "PATH=" DEFAULT_PATH_COMPAT, NULL, /* container */ NULL, /* TERM */ NULL, /* HOME */ @@ -3426,17 +3426,17 @@ static int inner_child( n_env++; if (home || !uid_is_valid(arg_uid) || arg_uid == 0) - if (asprintf((char**)(envp + n_env++), "HOME=%s", home ?: "/root") < 0) + if (asprintf(envp + n_env++, "HOME=%s", home ?: "/root") < 0) return log_oom(); if (arg_user || !uid_is_valid(arg_uid) || arg_uid == 0) - if (asprintf((char**)(envp + n_env++), "USER=%s", arg_user ?: "root") < 0 || - asprintf((char**)(envp + n_env++), "LOGNAME=%s", arg_user ? arg_user : "root") < 0) + if (asprintf(envp + n_env++, "USER=%s", arg_user ?: "root") < 0 || + asprintf(envp + n_env++, "LOGNAME=%s", arg_user ? arg_user : "root") < 0) return log_oom(); assert(!sd_id128_is_null(arg_uuid)); - if (asprintf((char**)(envp + n_env++), "container_uuid=%s", id128_to_uuid_string(arg_uuid, as_uuid)) < 0) + if (asprintf(envp + n_env++, "container_uuid=%s", id128_to_uuid_string(arg_uuid, as_uuid)) < 0) return log_oom(); if (fdset_size(fds) > 0) { @@ -3444,11 +3444,11 @@ static int inner_child( if (r < 0) return log_error_errno(r, "Failed to unset O_CLOEXEC for file descriptors."); - if ((asprintf((char **)(envp + n_env++), "LISTEN_FDS=%u", fdset_size(fds)) < 0) || - (asprintf((char **)(envp + n_env++), "LISTEN_PID=1") < 0)) + if ((asprintf(envp + n_env++, "LISTEN_FDS=%u", fdset_size(fds)) < 0) || + (asprintf(envp + n_env++, "LISTEN_PID=1") < 0)) return log_oom(); } - if (asprintf((char **)(envp + n_env++), "NOTIFY_SOCKET=%s", NSPAWN_NOTIFY_SOCKET_PATH) < 0) + if (asprintf(envp + n_env++, "NOTIFY_SOCKET=%s", NSPAWN_NOTIFY_SOCKET_PATH) < 0) return log_oom(); if (arg_n_credentials > 0) { @@ -3458,7 +3458,7 @@ static int inner_child( n_env++; } - env_use = strv_env_merge(3, envp, os_release_pairs, arg_setenv); + env_use = strv_env_merge(envp, os_release_pairs, arg_setenv); if (!env_use) return log_oom(); diff --git a/src/run/run.c b/src/run/run.c index 0be974f03ab..993f1bc4f44 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -1526,7 +1526,7 @@ static int start_transient_scope(sd_bus *bus) { return log_error_errno(errno, "Failed to change UID to " UID_FMT ": %m", uid); } - env = strv_env_merge(3, environ, user_env, arg_environment); + env = strv_env_merge(environ, user_env, arg_environment); if (!env) return log_oom(); diff --git a/src/test/test-env-util.c b/src/test/test-env-util.c index ed4580e4aff..5bf130ed86b 100644 --- a/src/test/test-env-util.c +++ b/src/test/test-env-util.c @@ -81,7 +81,7 @@ static void test_strv_env_merge(void) { b = strv_new("FOO=KKK", "FOO=", "PIEP=", "SCHLUMPF=SMURFF", "NANANANA=YES"); assert_se(b); - r = strv_env_merge(2, a, b); + r = strv_env_merge(a, b); assert_se(r); assert_se(streq(r[0], "FOO=")); assert_se(streq(r[1], "WALDO="));