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

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