X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=24f9e7ee58338c4ad293012e7811671e3a1dad9e;hp=5b795d4a246e1e2be581479cb46acdd848b35647;hb=fabe5c0e5fce730aa66e10a9c4f9fdd443d7aeda;hpb=4d1a69043862ed979642f5688097160355d4cc81 diff --git a/src/shared/util.c b/src/shared/util.c index 5b795d4a2..24f9e7ee5 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; @@ -1063,10 +1068,10 @@ int get_process_exe(pid_t pid, char **name) { } static int get_process_id(pid_t pid, const char *field, uid_t *uid) { - char *p; - FILE *f; - int r; + _cleanup_fclose_ FILE *f = NULL; + _cleanup_free_ char *p = NULL; + assert(field); assert(uid); if (pid == 0) @@ -1076,21 +1081,11 @@ static int get_process_id(pid_t pid, const char *field, uid_t *uid) { return -ENOMEM; f = fopen(p, "re"); - free(p); - if (!f) return -errno; - while (!feof(f)) { - char line[LINE_MAX], *l; - - if (!fgets(line, sizeof(line), f)) { - if (feof(f)) - break; - - r = -errno; - goto finish; - } + FOREACH_LINE(f, line, return -errno) { + char *l; l = strstrip(line); @@ -1100,17 +1095,11 @@ static int get_process_id(pid_t pid, const char *field, uid_t *uid) { l[strcspn(l, WHITESPACE)] = 0; - r = parse_uid(l, uid); - goto finish; + return parse_uid(l, uid); } } - r = -EIO; - -finish: - fclose(f); - - return r; + return -EIO; } int get_process_uid(pid_t pid, uid_t *uid) { @@ -5920,3 +5909,82 @@ int on_ac_power(void) { return found_online || !found_offline; } + +static int search_and_fopen_internal(const char *path, const char *mode, char **search, FILE **_f) { + char **i; + + assert(path); + assert(mode); + assert(_f); + + if (!path_strv_canonicalize_uniq(search)) + return -ENOMEM; + + STRV_FOREACH(i, search) { + _cleanup_free_ char *p = NULL; + FILE *f; + + p = strjoin(*i, "/", path, NULL); + if (!p) + return -ENOMEM; + + f = fopen(p, mode); + if (f) { + *_f = f; + return 0; + } + + if (errno != ENOENT) + return -errno; + } + + return -ENOENT; +} + +int search_and_fopen(const char *path, const char *mode, const char **search, FILE **_f) { + _cleanup_strv_free_ char **copy = NULL; + + assert(path); + assert(mode); + assert(_f); + + if (path_is_absolute(path)) { + FILE *f; + + f = fopen(path, mode); + if (f) { + *_f = f; + return 0; + } + + return -errno; + } + + copy = strv_copy((char**) search); + if (!copy) + return -ENOMEM; + + return search_and_fopen_internal(path, mode, copy, _f); +} + +int search_and_fopen_nulstr(const char *path, const char *mode, const char *search, FILE **_f) { + _cleanup_strv_free_ char **s = NULL; + + if (path_is_absolute(path)) { + FILE *f; + + f = fopen(path, mode); + if (f) { + *_f = f; + return 0; + } + + return -errno; + } + + s = strv_split_nulstr(search); + if (!s) + return -ENOMEM; + + return search_and_fopen_internal(path, mode, s, _f); +}