From: Zbigniew Jędrzejewski-Szmek Date: Sat, 20 Feb 2021 18:25:32 +0000 (+0100) Subject: basic/env-util: add putenv_dup() X-Git-Tag: v248-rc1~8^2~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fa256f43e7ad6cafabc0ad89a0aee143670e1cca;p=thirdparty%2Fsystemd.git basic/env-util: add putenv_dup() --- diff --git a/src/basic/env-util.c b/src/basic/env-util.c index df24cb935d3..7fa598a3b53 100644 --- a/src/basic/env-util.c +++ b/src/basic/env-util.c @@ -768,6 +768,21 @@ int set_unset_env(const char *name, const char *value, bool overwrite) { return 0; } +int putenv_dup(const char *assignment, bool override) { + const char *e, *n; + + e = strchr(assignment, '='); + if (!e) + return -EINVAL; + + n = strndupa(assignment, e - assignment); + + /* This is like putenv(), but uses setenv() so that our memory doesn't become part of environ[]. */ + if (setenv(n, e + 1, override) < 0) + return -errno; + return 0; +} + int setenv_systemd_exec_pid(bool update_only) { char str[DECIMAL_STR_MAX(pid_t)]; const char *e; diff --git a/src/basic/env-util.h b/src/basic/env-util.h index 7ba8488af7f..1fbe7e42709 100644 --- a/src/basic/env-util.h +++ b/src/basic/env-util.h @@ -58,6 +58,9 @@ int getenv_bool_secure(const char *p); /* Like setenv, but calls unsetenv if value == NULL. */ int set_unset_env(const char *name, const char *value, bool overwrite); +/* Like putenv, but duplicates the memory like setenv. */ +int putenv_dup(const char *assignment, bool override); + int setenv_systemd_exec_pid(bool update_only); /* Parses and does sanity checks on an environment variable containing diff --git a/src/test/test-env-util.c b/src/test/test-env-util.c index 77b8952f83c..1e2e9365927 100644 --- a/src/test/test-env-util.c +++ b/src/test/test-env-util.c @@ -361,6 +361,19 @@ static void test_env_assignment_is_valid(void) { assert_se(!env_assignment_is_valid("głąb=printf \"\x1b]0;\x07\"")); } +static void test_putenv_dup(void) { + log_info("/* %s */", __func__); + + assert_se(putenv_dup("A=a1", true) == 0); + assert_se(streq(getenv("A"), "a1")); + assert_se(putenv_dup("A=a1", true) == 0); + assert_se(streq(getenv("A"), "a1")); + assert_se(putenv_dup("A=a2", false) == 0); + assert_se(streq(getenv("A"), "a1")); + assert_se(putenv_dup("A=a2", true) == 0); + assert_se(streq(getenv("A"), "a2")); +} + static void test_setenv_systemd_exec_pid(void) { _cleanup_free_ char *saved = NULL; const char *e; @@ -416,6 +429,7 @@ int main(int argc, char *argv[]) { test_env_name_is_valid(); test_env_value_is_valid(); test_env_assignment_is_valid(); + test_putenv_dup(); test_setenv_systemd_exec_pid(); return 0;