Blame SOURCES/0241-lib-add-get-env-variable-from-a-file.patch

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