From 41988b7f1cc26245483d1677092989035a5304d8 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Wed, 22 May 2019 17:18:23 +0100 Subject: [PATCH] Move code only used for Wine detection into wine file --- daemon/gamemode-env.c | 96 ------------------------------------------ daemon/gamemode-proc.c | 61 --------------------------- daemon/gamemode-wine.c | 81 +++++++++++++++++++++++++++++++++++ daemon/gamemode.h | 14 ------ 4 files changed, 81 insertions(+), 171 deletions(-) delete mode 100644 daemon/gamemode-env.c delete mode 100644 daemon/gamemode-proc.c diff --git a/daemon/gamemode-env.c b/daemon/gamemode-env.c deleted file mode 100644 index 6a1786b..0000000 --- a/daemon/gamemode-env.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - -Copyright (c) 2017-2019, Feral Interactive -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Feral Interactive nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - - */ - -#define _GNU_SOURCE - -#include "gamemode.h" - -#include -#include -#include -#include -#include -#include - -/** - * Lookup the process environment for a specific variable or return NULL. - * Requires an open directory FD from /proc/PID. - */ -char *game_mode_lookup_proc_env(const procfd_t 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. - */ -char *game_mode_lookup_user_home(void) -{ - /* Try loading env HOME first */ - const char *home = secure_getenv("HOME"); - if (!home) { - /* If HOME is not defined (or out of context), fall back to passwd */ - struct passwd *pw = getpwuid(getuid()); - if (!pw) - return NULL; - home = pw->pw_dir; - } - - /* Try to allocate into our heap */ - return home ? strdup(home) : NULL; -} diff --git a/daemon/gamemode-proc.c b/daemon/gamemode-proc.c deleted file mode 100644 index daea7b7..0000000 --- a/daemon/gamemode-proc.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - -Copyright (c) 2017-2019, Feral Interactive -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Feral Interactive nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - - */ - -#define _GNU_SOURCE - -#include "gamemode.h" -#include "helpers.h" - -#include -#include -#include - -/** - * Opens the process environment for a specific PID and returns - * a file descriptor to the directory /proc/PID. Doing it that way prevents - * the directory going MIA when a process exits while we are looking at it - * and allows us to handle fewer error cases. - */ -procfd_t game_mode_open_proc(const pid_t pid) -{ - char buffer[PATH_MAX]; - const char *proc_path = buffered_snprintf(buffer, "/proc/%d", pid); - - return proc_path ? open(proc_path, O_RDONLY | O_CLOEXEC) : INVALID_PROCFD; -} - -/** - * Closes the process environment. - */ -int game_mode_close_proc(const procfd_t procfd) -{ - return close(procfd); -} diff --git a/daemon/gamemode-wine.c b/daemon/gamemode-wine.c index 4548dc0..b23f8e5 100644 --- a/daemon/gamemode-wine.c +++ b/daemon/gamemode-wine.c @@ -37,7 +37,11 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#include +#include +#include #include +#include #include /** @@ -56,6 +60,83 @@ static bool game_mode_detect_wine_loader(const char *exe) return (strtail(exe, "/wine") || strtail(exe, "/wine64")); } +/** + * Opens the process environment for a specific PID and returns + * a file descriptor to the directory /proc/PID. Doing it that way prevents + * the directory going MIA when a process exits while we are looking at it + * and allows us to handle fewer error cases. + */ +static procfd_t game_mode_open_proc(const pid_t pid) +{ + char buffer[PATH_MAX]; + const char *proc_path = buffered_snprintf(buffer, "/proc/%d", pid); + + return proc_path ? open(proc_path, O_RDONLY | O_CLOEXEC) : INVALID_PROCFD; +} + +/** + * Closes the process environment. + */ +static int game_mode_close_proc(const procfd_t procfd) +{ + return close(procfd); +} + +/** + * 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(const procfd_t 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. + */ +static char *game_mode_lookup_user_home(void) +{ + /* Try loading env HOME first */ + const char *home = secure_getenv("HOME"); + if (!home) { + /* If HOME is not defined (or out of context), fall back to passwd */ + struct passwd *pw = getpwuid(getuid()); + if (!pw) + return NULL; + home = pw->pw_dir; + } + + /* Try to allocate into our heap */ + return home ? strdup(home) : NULL; +} + /** * Attempt to resolve the exe for wine-preloader. * This function is used if game_mode_context_find_exe() identified the diff --git a/daemon/gamemode.h b/daemon/gamemode.h index 21bc238..ae89f6f 100644 --- a/daemon/gamemode.h +++ b/daemon/gamemode.h @@ -116,13 +116,6 @@ GameModeConfig *game_mode_config_from_context(const GameModeContext *context); */ int game_mode_reload_config(GameModeContext *context); -/** gamemode-env.c - * Provides internal API functions specific to working environment - * variables. - */ -char *game_mode_lookup_proc_env(const procfd_t proc_fd, const char *var); -char *game_mode_lookup_user_home(void); - /** gamemode-ioprio.c * Provides internal API functions specific to adjusting process * IO priorities. @@ -130,13 +123,6 @@ char *game_mode_lookup_user_home(void); int game_mode_get_ioprio(const pid_t client); void game_mode_apply_ioprio(const GameModeContext *self, const pid_t client, int expected); -/** gamemode-proc.c - * Provides internal API functions specific to working with process - * environments. - */ -procfd_t game_mode_open_proc(const pid_t pid); -int game_mode_close_proc(const procfd_t procfd); - /** gamemode-sched.c * Provides internal API functions specific to adjusting process * scheduling.