|
|
4b6aa8 |
From afe0c36d832df68c19373b2a99abba4fc840f0e1 Mon Sep 17 00:00:00 2001
|
|
|
4b6aa8 |
From: Martin Kutlak <mkutlak@redhat.com>
|
|
|
4b6aa8 |
Date: Tue, 21 May 2019 10:42:53 +0200
|
|
|
4b6aa8 |
Subject: [PATCH] lib: add get env variable from a file
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
Introduced a new argument called 'delim' because /proc/PID/environ is
|
|
|
4b6aa8 |
delimited with 0 but FILENAME_ENVIRON is escaped version of that file
|
|
|
4b6aa8 |
with '\0's replaced by '\n'.
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
While /proc/PID/environ entries are always delimted by '\0' (even the
|
|
|
4b6aa8 |
last one), other files might not use this style and the function must
|
|
|
4b6aa8 |
handle EOF without the entry delimiter.
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
Cherry-picked from https://github.com/abrt/libreport/commit/a71e4149c85212c72af0cc67c5b99a5029491ed2
|
|
|
4b6aa8 |
---
|
|
|
4b6aa8 |
src/include/internal_libreport.h | 2 ++
|
|
|
4b6aa8 |
src/lib/get_cmdline.c | 38 ++++++++++++++++++++++++++------
|
|
|
4b6aa8 |
2 files changed, 33 insertions(+), 7 deletions(-)
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
diff --git a/src/include/internal_libreport.h b/src/include/internal_libreport.h
|
|
|
4b6aa8 |
index d7bab4e..fc0242c 100644
|
|
|
4b6aa8 |
--- a/src/include/internal_libreport.h
|
|
|
4b6aa8 |
+++ b/src/include/internal_libreport.h
|
|
|
4b6aa8 |
@@ -638,6 +638,8 @@ struct strbuf *strbuf_prepend_strfv(struct strbuf *strbuf,
|
|
|
4b6aa8 |
char* get_cmdline(pid_t pid);
|
|
|
4b6aa8 |
#define get_environ libreport_get_environ
|
|
|
4b6aa8 |
char* get_environ(pid_t pid);
|
|
|
4b6aa8 |
+#define get_env_variable_ext libreport_get_env_variable_ext
|
|
|
4b6aa8 |
+int get_env_variable_ext(int fd, char delim, const char *name, char **value);
|
|
|
4b6aa8 |
#define get_env_variable libreport_get_env_variable
|
|
|
4b6aa8 |
int get_env_variable(pid_t pid, const char *name, char **value);
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
diff --git a/src/lib/get_cmdline.c b/src/lib/get_cmdline.c
|
|
|
4b6aa8 |
index 0fc0cbf..9e83994 100644
|
|
|
4b6aa8 |
--- a/src/lib/get_cmdline.c
|
|
|
4b6aa8 |
+++ b/src/lib/get_cmdline.c
|
|
|
4b6aa8 |
@@ -149,15 +149,20 @@ char* get_environ(pid_t pid)
|
|
|
4b6aa8 |
return get_escaped(path, '\n');
|
|
|
4b6aa8 |
}
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
-int get_env_variable(pid_t pid, const char *name, char **value)
|
|
|
4b6aa8 |
+int get_env_variable_ext(int fd, char delim, const char *name, char **value)
|
|
|
4b6aa8 |
{
|
|
|
4b6aa8 |
- char path[sizeof("/proc/%lu/environ") + sizeof(long)*3];
|
|
|
4b6aa8 |
- snprintf(path, sizeof(path), "/proc/%lu/environ", (long)pid);
|
|
|
4b6aa8 |
+ int workfd = dup(fd);
|
|
|
4b6aa8 |
+ if (workfd < 0)
|
|
|
4b6aa8 |
+ {
|
|
|
4b6aa8 |
+ perror_msg("dup()");
|
|
|
4b6aa8 |
+ return -errno;
|
|
|
4b6aa8 |
+ }
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
- FILE *fenv = fopen(path, "re");
|
|
|
4b6aa8 |
+ FILE *fenv = fdopen(workfd, "re");
|
|
|
4b6aa8 |
if (fenv == NULL)
|
|
|
4b6aa8 |
{
|
|
|
4b6aa8 |
- pwarn_msg("Failed to open environ file");
|
|
|
4b6aa8 |
+ close(workfd);
|
|
|
4b6aa8 |
+ perror_msg("fdopen()");
|
|
|
4b6aa8 |
return -errno;
|
|
|
4b6aa8 |
}
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
@@ -177,17 +182,18 @@ int get_env_variable(pid_t pid, const char *name, char **value)
|
|
|
4b6aa8 |
i = 0;
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
/* Read to the end of variable entry */
|
|
|
4b6aa8 |
- while ((c = fgetc(fenv)) != EOF && c !='\0')
|
|
|
4b6aa8 |
+ while ((c = fgetc(fenv)) != EOF && c != delim)
|
|
|
4b6aa8 |
++i;
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
/* Go to the next entry if the read entry isn't the searched variable */
|
|
|
4b6aa8 |
if (skip)
|
|
|
4b6aa8 |
continue;
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
+ const int eof = c != EOF;
|
|
|
4b6aa8 |
*value = xmalloc(i+1);
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
/* i+1 because we didn't count '\0' */
|
|
|
4b6aa8 |
- if (fseek(fenv, -(i+1), SEEK_CUR) < 0)
|
|
|
4b6aa8 |
+ if (fseek(fenv, -(i+eof), SEEK_CUR) < 0)
|
|
|
4b6aa8 |
error_msg_and_die("Failed to seek");
|
|
|
4b6aa8 |
|
|
|
4b6aa8 |
if (fread(*value, 1, i, fenv) != i)
|
|
|
4b6aa8 |
@@ -201,3 +207,21 @@ int get_env_variable(pid_t pid, const char *name, char **value)
|
|
|
4b6aa8 |
fclose(fenv);
|
|
|
4b6aa8 |
return 0;
|
|
|
4b6aa8 |
}
|
|
|
4b6aa8 |
+
|
|
|
4b6aa8 |
+int get_env_variable(pid_t pid, const char *name, char **value)
|
|
|
4b6aa8 |
+{
|
|
|
4b6aa8 |
+ char path[sizeof("/proc/%lu/environ") + sizeof(long)*3];
|
|
|
4b6aa8 |
+ snprintf(path, sizeof(path), "/proc/%lu/environ", (long)pid);
|
|
|
4b6aa8 |
+
|
|
|
4b6aa8 |
+ const int envfd = open(path, O_RDONLY);
|
|
|
4b6aa8 |
+ if (envfd < 0)
|
|
|
4b6aa8 |
+ {
|
|
|
4b6aa8 |
+ pwarn_msg("Failed to open environ file");
|
|
|
4b6aa8 |
+ return -errno;
|
|
|
4b6aa8 |
+ }
|
|
|
4b6aa8 |
+
|
|
|
4b6aa8 |
+ const int r = get_env_variable_ext(envfd, '\0', name, value);
|
|
|
4b6aa8 |
+ close(envfd);
|
|
|
4b6aa8 |
+
|
|
|
4b6aa8 |
+ return r;
|
|
|
4b6aa8 |
+}
|
|
|
4b6aa8 |
--
|
|
|
4b6aa8 |
2.21.0
|
|
|
4b6aa8 |
|