- if (!key)
- p += strcspn(p, separator);
- }
-
-fail:
- free(contents);
- return r;
-}
-
-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;
-
- assert(fname);
- assert(rl);
-
- f = fopen(fname, "re");
- if (!f)
- return -errno;
-
- while (!feof(f)) {
- char l[LINE_MAX], *p, *u, *cs;
- char **t;
-
- if (!fgets(l, sizeof(l), f)) {
- if (!feof(f))
- return -errno;
- else if (!c)
- break;
- }
-
- cs = endswith(l, "\\\n");
- if (cs) {
- *cs = '\0';
- b = strappend(c, l);
- if (!b)
- return log_oom();
-
- free(c);
- c = b;
- *l = '\0';
- continue;
- }
-
- if (c) {
- b = strappend(c, l);
- if (!b)
- return log_oom();
-
- free(c);
- c = b;
- }
-
- p = strstrip(c ? c : l);
-
- if (!*p)
- continue;
-
- if (strchr(COMMENTS, *p))
- continue;
-
- u = normalize_env_assignment(p);
- if (!u)
- return log_oom();
-
- free(c);
- c = NULL;
-
- t = strv_append(m, u);
- free(u);
-
- if (!t)
- return log_oom();
-
- strv_free(m);
- m = t;
- }
-
- *rl = m;
- m = NULL;
-
- return 0;
-}
-
-int write_env_file(const char *fname, char **l) {
- char **i, *p;
- FILE *f;
- int r;
-
- r = fopen_temporary(fname, &f, &p);
- if (r < 0)
- return r;
-
- fchmod_umask(fileno(f), 0644);
-
- errno = 0;
- STRV_FOREACH(i, l) {
- fputs(*i, f);
- fputc('\n', f);
- }
-
- fflush(f);
-
- if (ferror(f)) {
- if (errno != 0)
- r = -errno;
- else
- r = -EIO;
- } else {
- if (rename(p, fname) < 0)
- r = -errno;
- else
- r = 0;
- }
-
- if (r < 0)
- unlink(p);
-
- fclose(f);
- free(p);
-
- return r;
-}
-
-char *truncate_nl(char *s) {
- assert(s);
-
- s[strcspn(s, NEWLINE)] = 0;
- return s;
-}
-
-int get_process_comm(pid_t pid, char **name) {
- int r;
-
- assert(name);
-
- if (pid == 0)
- r = read_one_line_file("/proc/self/comm", name);
- else {
- char *p;
- if (asprintf(&p, "/proc/%lu/comm", (unsigned long) pid) < 0)
- return -ENOMEM;
-
- r = read_one_line_file(p, name);
- free(p);
- }
-
- return r;
-}
-
-int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
- char *r = NULL, *k;
- int c;
- FILE *f;
-
- assert(line);
-
- if (pid == 0)
- f = fopen("/proc/self/cmdline", "re");
- else {
- char *p;
- if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0)
- return -ENOMEM;
-
- f = fopen(p, "re");
- free(p);
- }
-
- if (!f)
- return -errno;
- if (max_length == 0) {
- size_t len = 1;
- while ((c = getc(f)) != EOF) {
- k = realloc(r, len+1);
- if (k == NULL) {
- free(r);
- fclose(f);
- return -ENOMEM;
- }
- r = k;
- r[len-1] = isprint(c) ? c : ' ';
- r[len] = 0;
- len++;
- }
- } else {
- bool space = false;
- size_t left;
- r = new(char, max_length);
- if (!r) {
- fclose(f);
- return -ENOMEM;
- }
-
- k = r;
- left = max_length;
- while ((c = getc(f)) != EOF) {
-
- if (isprint(c)) {
- if (space) {
- if (left <= 4)
- break;
-
- *(k++) = ' ';
- left--;
- space = false;
- }
-
- if (left <= 4)
- break;
-
- *(k++) = (char) c;
- left--;
- } else
- space = true;
- }
-
- if (left <= 4) {
- size_t n = MIN(left-1, 3U);
- memcpy(k, "...", n);
- k[n] = 0;
- } else
- *k = 0;
- }
-
- fclose(f);
-
- /* Kernel threads have no argv[] */
- if (r == NULL || r[0] == 0) {
- char *t;
- int h;
-
- free(r);
-
- if (!comm_fallback)
- return -ENOENT;
-
- h = get_process_comm(pid, &t);
- if (h < 0)
- return h;
-
- r = strjoin("[", t, "]", NULL);
- free(t);
-
- if (!r)
- return -ENOMEM;
- }
-
- *line = r;
- return 0;
-}
-
-int is_kernel_thread(pid_t pid) {
- char *p;
- size_t count;
- char c;
- bool eof;
- FILE *f;
-
- if (pid == 0)
- return 0;
-
- if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0)
- return -ENOMEM;
-
- f = fopen(p, "re");
- free(p);
-
- if (!f)
- return -errno;
-
- count = fread(&c, 1, 1, f);
- eof = feof(f);
- fclose(f);
-
- /* Kernel threads have an empty cmdline */
-
- if (count <= 0)
- return eof ? 1 : -errno;
-
- return 0;
-}
-
-int get_process_exe(pid_t pid, char **name) {
- int r;
-
- assert(name);
-
- if (pid == 0)
- r = readlink_malloc("/proc/self/exe", name);
- else {
- char *p;
- if (asprintf(&p, "/proc/%lu/exe", (unsigned long) pid) < 0)
- return -ENOMEM;
-
- r = readlink_malloc(p, name);
- free(p);
- }
-
- return r;
-}
-
-static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
- char *p;
- FILE *f;
- int r;
-
- assert(uid);
-
- if (pid == 0)
- return getuid();
-
- if (asprintf(&p, "/proc/%lu/status", (unsigned long) pid) < 0)
- 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;
- }
-
- l = strstrip(line);