]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic/env-util: add a mode where we pull in the variable value from environment
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 10 Aug 2021 15:03:12 +0000 (17:03 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 11 Aug 2021 07:16:05 +0000 (09:16 +0200)
src/basic/env-util.c
src/basic/env-util.h
src/test/test-env-util.c

index 0c30ddc277505c11815ad43a550a6637a7641a54..cb4912564414e57d3f5ff6013157cf819e473fbd 100644 (file)
@@ -421,6 +421,32 @@ int strv_env_replace_strdup(char ***l, const char *assignment) {
         return strv_env_replace_consume(l, p);
 }
 
+int strv_env_replace_strdup_passthrough(char ***l, const char *assignment) {
+        /* Like strv_env_replace_strdup(), but pulls the variable from the environment of
+         * the calling program, if a variable name without value is specified.
+         */
+        char *p;
+
+        if (strchr(assignment, '=')) {
+                if (!env_assignment_is_valid(assignment))
+                        return -EINVAL;
+
+                p = strdup(assignment);
+        } else {
+                if (!env_name_is_valid(assignment))
+                        return -EINVAL;
+
+                /* If we can't find the variable in our environment, we will use
+                 * the empty string. This way "passthrough" is equivalent to passing
+                 * --setenv=FOO=$FOO in the shell. */
+                p = strjoin(assignment, "=", secure_getenv(assignment));
+        }
+        if (!p)
+                return -ENOMEM;
+
+        return strv_env_replace_consume(l, p);
+}
+
 int strv_env_assign(char ***l, const char *key, const char *value) {
         if (!env_name_is_valid(key))
                 return -EINVAL;
index 18d10ebab8f07bde3c0919623dc18a088c49716a..bee284b1684245885f608d63f62430f849613faf 100644 (file)
@@ -47,6 +47,7 @@ char **strv_env_unset(char **l, const char *p); /* In place ... */
 char **strv_env_unset_many(char **l, ...) _sentinel_;
 int strv_env_replace_consume(char ***l, char *p); /* In place ... */
 int strv_env_replace_strdup(char ***l, const char *assignment);
+int strv_env_replace_strdup_passthrough(char ***l, const char *assignment);
 int strv_env_assign(char ***l, const char *key, const char *value);
 
 char *strv_env_get_n(char **l, const char *name, size_t k, unsigned flags) _pure_;
index 91c3c252de42695b694664019d375966fd4e536b..c689d5590ee3fe48005d26022262908b57a458c7 100644 (file)
@@ -105,6 +105,7 @@ static void test_strv_env_replace_strdup(void) {
         assert_se(strv_env_replace_strdup(&a, "a=a") == 1);
         assert_se(strv_env_replace_strdup(&a, "b=b") == 1);
         assert_se(strv_env_replace_strdup(&a, "a=A") == 0);
+        assert_se(strv_env_replace_strdup(&a, "c") == -EINVAL);
 
         assert_se(strv_length(a) == 2);
         strv_sort(a);
@@ -112,6 +113,27 @@ static void test_strv_env_replace_strdup(void) {
         assert_se(streq(a[1], "b=b"));
 }
 
+static void test_strv_env_replace_strdup_passthrough(void) {
+        log_info("/* %s */", __func__);
+
+        _cleanup_strv_free_ char **a = NULL;
+
+        assert_se(putenv((char*) "a=a") == 0);
+        assert_se(putenv((char*) "b=") == 0);
+        assert_se(unsetenv("c") == 0);
+
+        assert_se(strv_env_replace_strdup_passthrough(&a, "a") == 1);
+        assert_se(strv_env_replace_strdup_passthrough(&a, "b") == 1);
+        assert_se(strv_env_replace_strdup_passthrough(&a, "c") == 1);
+        assert_se(strv_env_replace_strdup_passthrough(&a, "a") == 0);
+        assert_se(strv_env_replace_strdup_passthrough(&a, "$a") == -EINVAL);
+
+        assert_se(strv_length(a) == 3);
+        assert_se(streq(a[0], "a=a"));
+        assert_se(streq(a[1], "b="));
+        assert_se(streq(a[2], "c="));
+}
+
 static void test_strv_env_assign(void) {
         log_info("/* %s */", __func__);
 
@@ -415,6 +437,7 @@ int main(int argc, char *argv[]) {
         test_strv_env_unset();
         test_strv_env_merge();
         test_strv_env_replace_strdup();
+        test_strv_env_replace_strdup_passthrough();
         test_strv_env_assign();
         test_env_strv_get_n();
         test_replace_env(false);