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
This commit is contained in:
Michal Vyskocil 2013-01-18 10:05:10 +01:00 committed by Zbigniew Jędrzejewski-Szmek
parent c3a7cfb7de
commit 565d91fdf1
2 changed files with 43 additions and 8 deletions

View file

@ -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 (").</para>

View file

@ -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;