diff --git a/daemon/gamemode.c b/daemon/gamemode.c index 22e3d2e..a3da4bc 100644 --- a/daemon/gamemode.c +++ b/daemon/gamemode.c @@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "ioprio.h" #include "logging.h" +#include #include #include #include @@ -45,6 +46,7 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include #include #include @@ -673,6 +675,42 @@ GameModeContext *game_mode_context_instance() return &instance; } +/** + * Lookup the process environment for a specific variable or return NULL. + * Requires an open directory FD from /proc/PID. + */ +static char *game_mode_lookup_proc_env(int proc_fd, const char *var) +{ + char *environ = NULL; + + int fd = openat(proc_fd, "environ", O_RDONLY | O_CLOEXEC); + if (fd != -1) { + FILE *stream = fdopen(fd, "r"); + if (stream) { + /* Read every \0 terminated line from the environment */ + char *line = NULL; + size_t len = 0; + size_t pos = strlen(var) + 1; + while (!environ && (getdelim(&line, &len, 0, stream) != -1)) { + /* Find a match including the "=" suffix */ + if ((len > pos) && (strncmp(line, var, strlen(var)) == 0) && (line[pos - 1] == '=')) + environ = strndup(line + pos, len - pos); + } + free(line); + fclose(stream); + } else + close(fd); + } + + /* If found variable is empty, skip it */ + if (environ && !strlen(environ)) { + free(environ); + environ = NULL; + } + + return environ; +} + /** * Lookup the home directory of the user in a safe way. */