Commented lines are ignored by default and are considered as end of a definition. If they ends on a backslash, they are just ignored and a next line is considered as a part of a definition.
FOO=one \ two will be evaluated as FOO="one two", where FOO=one \ two will result in FOO="one" and two. --- src/shared/util.c | 38 +++++++++++++++------- src/shared/util.h | 1 + src/test/test-unit-file.c | 79 ++++++++++++++++++++++++++++++++++++--------- 3 files changed, 91 insertions(+), 27 deletions(-) diff --git a/src/shared/util.c b/src/shared/util.c index 4a75996..06bfdde 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -791,21 +791,32 @@ int load_env_file(const char *fname, break; } - cs = endswith(l, "\\\n"); + p = strlstrip(l); + if (!p && !c) + continue; + + cs = endswith(p, "\\\n"); if (cs) { + + if (strchr(COMMENTS, *p)) + continue; + *cs = '\0'; - b = strappend(c, l); + b = strappend(c, p); if (!b) return log_oom(); free(c); c = b; - *l = '\0'; + *p = '\0'; continue; + + } else if (strchr(COMMENTS, *p)) { + *p = '\0'; } if (c) { - b = strappend(c, l); + b = strappend(c, p); if (!b) return log_oom(); @@ -813,7 +824,7 @@ int load_env_file(const char *fname, c = b; } - p = strstrip(c ? c : l); + p = strstrip(c ? c : p); if (!*p) { free(c); @@ -821,12 +832,6 @@ int load_env_file(const char *fname, continue; } - if (strchr(COMMENTS, *p)) { - free(c); - c = NULL; - continue; - } - u = normalize_env_assignment(p); if (!u) return log_oom(); @@ -1257,6 +1262,17 @@ int reset_all_signal_handlers(void) { return 0; } +char *strlstrip(char *s) { + char *e; + + /* Drops trailing whitespace. Modifies the string in + * place. Returns pointer to first non-space character */ + + s += strspn(s, WHITESPACE); + + return s; +} + char *strstrip(char *s) { char *e; diff --git a/src/shared/util.h b/src/shared/util.h index 223617c..3a47588 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -196,6 +196,7 @@ int readlink_and_canonicalize(const char *p, char **r); int reset_all_signal_handlers(void); +char *strlstrip(char *s); char *strstrip(char *s); char *delete_chars(char *s, const char *bad); char *truncate_nl(char *s); diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c index 8519131..d67e27e 100644 --- a/src/test/test-unit-file.c +++ b/src/test/test-unit-file.c @@ -193,17 +193,50 @@ static void test_config_parse_exec(void) { #define env_file_2 \ "a\\\n" -static void test_load_env_file_1(void) { - char _cleanup_strv_free_ **data = NULL; - int r; - +#define env_file_3 \ + "#SPAMD_ARGS=\"-d --socketpath=/var/lib/bulwark/spamd \\\n"\ + "#--nouser-config \\\n" \ + "normal=line\" \\\n" \ + " \n" \ + "FOO=one \\\n" \ + "two \\\n" \ + "#comment-with-backslash \\\n" \ + "three \\\n" \ + " \n" \ + "FOO=one \\\n" \ + "two \\\n" \ + "#comment-without-backslash \n" \ + "three \\\n" \ + " \\\n" \ + "four \n" \ + "wrong=conti\\ \n" \ + "nuation \n" \ + " \n" \ + "last=line \\\n" \ + "#this comment will be ignored \n" + +static void write_read_env_file(char ***data, const char* text) { char name[] = "/tmp/test-load-env-file.XXXXXX"; + int r, i; int _cleanup_close_ fd = mkstemp(name); assert(fd >= 0); - assert_se(write(fd, env_file_1, sizeof(env_file_1)) == sizeof(env_file_1)); - r = load_env_file(name, &data); + r = write(fd, text, strlen(text)+1); + assert_se(r == (int)strlen(text)+1); + + r = load_env_file(name, data); assert(r == 0); + + for(i = 0; *data && (*data)[i]; i++) + puts((*data)[i]); + + unlink(name); +} + +static void test_load_env_file_1(void) { + char _cleanup_strv_free_ **data = NULL; + write_read_env_file(&data, env_file_1); + assert(streq(data[0], "a")); assert(streq(data[1], "bc")); assert(streq(data[2], "def")); @@ -211,23 +244,36 @@ static void test_load_env_file_1(void) { assert(streq(data[4], "h")); assert(streq(data[5], "i\\")); assert(data[6] == NULL); - unlink(name); } static void test_load_env_file_2(void) { char _cleanup_strv_free_ **data = NULL; - int r; + write_read_env_file(&data, env_file_2); - char name[] = "/tmp/test-load-env-file.XXXXXX"; - int _cleanup_close_ fd = mkstemp(name); - assert(fd >= 0); - assert_se(write(fd, env_file_2, sizeof(env_file_2)) == sizeof(env_file_2)); - - r = load_env_file(name, &data); - assert(r == 0); assert(streq(data[0], "a")); assert(data[1] == NULL); - unlink(name); +} + +static void test_load_env_file_3(void) { + char **data = NULL; + write_read_env_file(&data, env_file_3); + + assert(data); + assert(streq(data[0], + "normal=line\"")); + assert(streq(data[1], + "FOO=one two three")); + assert(streq(data[2], + "FOO=one two")); + assert(streq(data[3], + "three four")); + assert(streq(data[4], + "wrong=conti\\")); + assert(streq(data[5], + "nuation")); + assert(streq(data[6], + "last=line")); + assert(data[7] == NULL); } #pragma GCC diagnostic push @@ -305,6 +351,7 @@ int main(int argc, char *argv[]) { test_config_parse_exec(); test_load_env_file_1(); test_load_env_file_2(); + test_load_env_file_3(); test_install_printf(); return 0; -- 1.7.10.4
signature.asc
Description: Digital signature
_______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel