From: Michal Vyskocil Date: Fri, 18 Jan 2013 09:05:10 +0000 (+0100) Subject: util: continuation support for load_env_file X-Git-Tag: v198~474 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=565d91fdf198b88f7c2d72c67cfc6c30341a3596;p=elogind.git util: continuation support for load_env_file Variable definitions can be written on more than one line - if each ends with a backslash, then is concatenated with a previous one. Only backslash and unix end of line (\n) are treated as a continuation. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=58083 [zj: squashed two patches together; cleaned up grammar; removed comment about ignoring trailing backslash -- it is not ignored.] Document continuation support in systemd.exec --- diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 71472b4f5..8a22ac013 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -299,9 +299,11 @@ contain new-line separated variable assignments. Empty lines and lines starting with ; or # will be ignored, - which may be used for commenting. The - parser strips leading and - trailing whitespace from the values + which may be used for commenting. A line + ending with a backslash will be concatenated + with the following one, allowing multiline variable + definitions. The parser strips leading + and trailing whitespace from the values of assignments, unless you use double quotes ("). diff --git a/src/shared/util.c b/src/shared/util.c index f75a81c60..08c0c2be1 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -780,6 +780,8 @@ int load_env_file( char ***rl) { FILE *f; + char *b; + char *c = NULL; char **m = NULL; int r; @@ -790,18 +792,45 @@ int load_env_file( return -errno; while (!feof(f)) { - char l[LINE_MAX], *p, *u; + char l[LINE_MAX], *p, *u, *cs; char **t; if (!fgets(l, sizeof(l), f)) { - if (feof(f)) + if(!feof(f)) { + r = -errno; + goto finish; + } + else if (!c) break; - r = -errno; - goto finish; } - p = strstrip(l); + cs = endswith(l, "\\\n"); + if (cs) { + + *cs = '\0'; + b = strappend(c, l); + if (!b) { + r = log_oom(); + goto finish; + } + free(c); + c = b; + *l = '\0'; + continue; + } + + if (c) { + b = strappend(c, l); + if (!b) { + r = log_oom(); + goto finish; + } + free(c); + c = b; + } + + p = strstrip(c ? c : l); if (!*p) continue; @@ -813,6 +842,8 @@ int load_env_file( r = log_oom(); goto finish; } + free(c); + c = NULL; t = strv_append(m, u); free(u); @@ -835,6 +866,8 @@ finish: if (f) fclose(f); + free(c); + strv_free(m); return r;