diff options
author | Lennart Poettering <lennart@poettering.net> | 2012-04-22 14:48:46 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2012-04-22 15:00:42 +0200 |
commit | ab94af9201496ea3aa59bbf2a01eb750fbd1c08a (patch) | |
tree | b62a3fcbea3779855a964e37e1415c75ad1c8816 /src/shared/util.c | |
parent | 144f0fc0c8a5e2f6b72179e2b5fb992474da24ad (diff) |
util: unify getenv() logic for other PID
Diffstat (limited to 'src/shared/util.c')
-rw-r--r-- | src/shared/util.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/shared/util.c b/src/shared/util.c index 317abb8016..ba24562839 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -6168,3 +6168,65 @@ int path_is_read_only_fs(const char *path) { return !!(st.f_flag & ST_RDONLY); } + +int getenv_for_pid(pid_t pid, const char *field, char **_value) { + char path[sizeof("/proc/")-1+10+sizeof("/environ")], *value = NULL; + int r; + FILE *f; + bool done = false; + size_t l; + + assert(field); + assert(_value); + + if (pid == 0) + pid = getpid(); + + snprintf(path, sizeof(path), "/proc/%lu/environ", (unsigned long) pid); + char_array_0(path); + + f = fopen(path, "re"); + if (!f) + return -errno; + + l = strlen(field); + r = 0; + + do { + char line[LINE_MAX]; + unsigned i; + + for (i = 0; i < sizeof(line)-1; i++) { + int c; + + c = getc(f); + if (_unlikely_(c == EOF)) { + done = true; + break; + } else if (c == 0) + break; + + line[i] = c; + } + line[i] = 0; + + if (memcmp(line, field, l) == 0 && line[l] == '=') { + value = strdup(line + l + 1); + if (!value) { + r = -ENOMEM; + break; + } + + r = 1; + break; + } + + } while (!done); + + fclose(f); + + if (r >= 0) + *_value = value; + + return r; +} |