From dfbacb6fe56db4820137e4b668c361168fbfe5ff Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 11 Feb 2013 05:36:54 +0100 Subject: util: rework load_env_file() Inner library calls should not invoke log_oom(), that's something for main programs, not library calls. Don't read through uninitialized memory if a file ends in a continuation line. Add comments for the non-obvious bits. Don't choke on comment lines that are continuation lines. Simplify some things. --- src/shared/util.c | 65 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 30 deletions(-) (limited to 'src/shared') diff --git a/src/shared/util.c b/src/shared/util.c index 1d30ea5851..29cb9f1e8d 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -766,77 +766,82 @@ fail: return r; } -int load_env_file(const char *fname, - char ***rl) { +int load_env_file(const char *fname, char ***rl) { - FILE _cleanup_fclose_ *f; - char *b; - char _cleanup_free_ *c = NULL; - char _cleanup_strv_free_ **m = NULL; + _cleanup_fclose_ FILE *f; + _cleanup_strv_free_ char **m = NULL; + _cleanup_free_ char *c = NULL; assert(fname); assert(rl); + /* This reads an environment file, but will not complain about + * any invalid assignments, that needs to be done by the + * caller */ + f = fopen(fname, "re"); if (!f) return -errno; while (!feof(f)) { - char l[LINE_MAX], *p, *u, *cs; - char **t; + char l[LINE_MAX], *p, *cs, *b; if (!fgets(l, sizeof(l), f)) { - if (!feof(f)) + if (ferror(f)) return -errno; - else if (!c) - break; + + /* The previous line was a continuation line? + * Let's process it now, before we leave the + * loop */ + if (c) + goto process; + + break; } + /* Is this a continuation line? If so, just append + * this to c, and go to next line right-away */ cs = endswith(l, "\\\n"); if (cs) { *cs = '\0'; b = strappend(c, l); if (!b) - return log_oom(); + return -ENOMEM; free(c); c = b; - *l = '\0'; continue; } + /* If the previous line was a continuation line, + * append the current line to it */ if (c) { b = strappend(c, l); if (!b) - return log_oom(); + return -ENOMEM; free(c); c = b; } + process: p = strstrip(c ? c : l); - if (!*p) - continue; + if (*p && !strchr(COMMENTS, *p)) { + _cleanup_free_ char *u; + int k; - if (strchr(COMMENTS, *p)) - continue; + u = normalize_env_assignment(p); + if (!u) + return -ENOMEM; - u = normalize_env_assignment(p); - if (!u) - return log_oom(); + k = strv_extend(&m, u); + if (k < 0) + return -ENOMEM; + } free(c); c = NULL; - - t = strv_append(m, u); - free(u); - - if (!t) - return log_oom(); - - strv_free(m); - m = t; } *rl = m; -- cgit v1.2.3-54-g00ecf