]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic/env-util: add putenv_dup()
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sat, 20 Feb 2021 18:25:32 +0000 (19:25 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 22 Feb 2021 19:10:55 +0000 (20:10 +0100)
src/basic/env-util.c
src/basic/env-util.h
src/test/test-env-util.c

index df24cb935d360d66f2d50bdaa81a967c5188d3c5..7fa598a3b533d660b8da1535634478807688fe42 100644 (file)
@@ -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;
index 7ba8488af7fd7e0cc33849d77bd2d6163feca7c1..1fbe7e4270992144bd0e85530291ff4c006ac08e 100644 (file)
@@ -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
index 77b8952f83c92cffb4f2edff38881e93d0621f74..1e2e9365927322f8b5a7aed0a657b49ad189dbf0 100644 (file)
@@ -361,6 +361,19 @@ static void test_env_assignment_is_valid(void) {
         assert_se(!env_assignment_is_valid("głąb=printf \"\x1b]0;<mock-chroot>\x07<mock-chroot>\""));
 }
 
+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;