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

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