From 589dda31a563024bb067270ee75afe6ef3ab73d6 Mon Sep 17 00:00:00 2001 From: Ikey Doherty Date: Fri, 10 Nov 2017 22:58:59 +0000 Subject: [PATCH] shim: Add new simplified variable management code This will allow us to extend the number of bootstrap variables we need to set up for snapd, and actually makes the existing code much simpler to follow when dealing with existing environmental variables. With this change we also introduce initial bootstrap for setting the PATH, as it's incorrect on entering the snap. This is part of the ongoing issue #30. Signed-off-by: Ikey Doherty --- src/shim/shim.c | 106 ++++++++++++++++++++++++------------------------ 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/src/shim/shim.c b/src/shim/shim.c index 00389b3..5203504 100644 --- a/src/shim/shim.c +++ b/src/shim/shim.c @@ -19,6 +19,7 @@ #include #include "../common/files.h" +#include "../common/log.h" #include "config.h" #include "lsi.h" @@ -52,74 +53,61 @@ "/var/lib/snapd/lib/gl/32:/var/lib/snapd/lib/gl:/usr/lib/glx-provider/default:/usr/lib32/" \ "glx-provider/default" #define SNAPD_DRIVERS_PATH "/usr/lib/dri:/usr/lib32/dri" + /** - * Set up the LD_AUDIT environment - respecting $SNAP if set + * Used to update a value in the environment, and perform a prepend if the variable + * is already set. */ -static void shim_set_audit_path(void) +static void shim_export_merge_vars(const char *var_name, const char *prefix, const char *value) { - const char *extra = NULL; - static char tgt[PATH_MAX] = { 0 }; + static char copy_buffer[PATH_MAX] = { 0 }; + const char *env_exist = NULL; + int ret = 0; -#ifdef HAVE_SNAPD_SUPPORT - /* For snapd, we need to prepend "$SNAP" into the path */ - extra = getenv("SNAP"); -#endif + env_exist = getenv(var_name); - if (snprintf(tgt, sizeof(tgt), "%s%s", extra ? extra : "", AUDIT_PATH) < 0) { - setenv("LD_AUDIT", AUDIT_PATH, 1); + ret = snprintf(copy_buffer, + sizeof(copy_buffer), + "%s%s%s%s", + prefix ? prefix : "", + value, + env_exist ? ":" : "", + env_exist ? env_exist : ""); + if (ret < 0) { + lsi_log_error("failed to update variable '%s'", var_name); return; } - setenv("LD_AUDIT", tgt, 1); + lsi_log_debug("%s = %s", var_name, copy_buffer); + + setenv(var_name, copy_buffer, 1); +} + +/** + * Set up the LD_AUDIT environment - respecting $SNAP if set + */ +static void shim_set_audit_path(const char *prefix) +{ + shim_export_merge_vars("LD_AUDIT", prefix, AUDIT_PATH); } /** * Set up LD_PRELOAD, respecting an existing LD_PRELOAD and forcing ourselves * to be first in the list. */ -static void shim_set_ld_preload(void) +static void shim_set_ld_preload(const char *prefix) { - const char *preload = NULL; - static char tgt[PATH_MAX] = { 0 }; - const char *extra = NULL; - -#ifdef HAVE_SNAPD_SUPPORT - /* For snapd, we need to prepend "$SNAP" into the path */ - extra = getenv("SNAP"); -#endif - - /* Always need to know about existing LD_PRELOAD */ - preload = getenv("LD_PRELOAD"); - - /* Set up string to include any SNAP prefix and existing LD_PRELOAD */ - if (snprintf(tgt, - sizeof(tgt), - "%s%s%s%s", - extra ? extra : "", - REDIRECT_PATH, - preload ? ":" : "", - preload ? preload : "") < 0) { - setenv("LD_PRELOAD", REDIRECT_PATH, 1); - return; - } - - setenv("LD_PRELOAD", tgt, 1); + shim_export_merge_vars("LD_PRELOAD", prefix, REDIRECT_PATH); } /** * Helper to get the Steam binary, respecting "$SNAP" if needed */ -static const char *shim_get_steam_binary(void) +static const char *shim_get_steam_binary(const char *prefix) { - const char *extra = NULL; static char tgt[PATH_MAX] = { 0 }; -#ifdef HAVE_SNAPD_SUPPORT - /* For snapd, we need to prepend "$SNAP" into the path */ - extra = getenv("SNAP"); -#endif - - if (snprintf(tgt, sizeof(tgt), "%s%s", extra ? extra : "", STEAM_BINARY) < 0) { + if (snprintf(tgt, sizeof(tgt), "%s%s", prefix ? prefix : "", STEAM_BINARY) < 0) { return STEAM_BINARY; } @@ -132,13 +120,20 @@ static const char *shim_get_steam_binary(void) * Currently this only sets up the snapd environmental variables, so that * we don't rely on separate bootstrap scripts out of tree. */ -static void shim_export_extra(void) -{ #ifdef HAVE_SNAPD_SUPPORT +static void shim_export_extra(const char *prefix) +{ setenv("LIBGL_DRIVERS_PATH", SNAPD_LIBRARY_PATH, 1); setenv("LD_LIBRARY_PATH", SNAPD_LIBRARY_PATH ":" SNAPD_DRIVERS_PATH, 1); -#endif + + shim_export_merge_vars("PATH", prefix, "/usr/bin"); + shim_export_merge_vars("PATH", prefix, "/bin"); } +#else +static void shim_export_extra(__lsi_unused__ const char *prefix) +{ +} +#endif int main(int argc, char **argv) { @@ -151,8 +146,13 @@ int main(int argc, char **argv) int i = 1; int8_t off = 0; int (*vfunc)(const char *, char *const argv[]) = NULL; + const char *operation_prefix = NULL; - lsi_exec_bin = shim_get_steam_binary(); +#ifdef HAVE_SNAPD_SUPPORT + operation_prefix = getenv("SNAP"); +#endif + + lsi_exec_bin = shim_get_steam_binary(operation_prefix); /* Initialise config */ if (!lsi_config_load(&config)) { @@ -167,7 +167,7 @@ int main(int argc, char **argv) } /* We might have additional variables we need to export */ - shim_export_extra(); + shim_export_extra(operation_prefix); /* Force STEAM_RUNTIME into the environment */ if (config.use_native_runtime) { @@ -176,19 +176,19 @@ int main(int argc, char **argv) #ifdef HAVE_LIBINTERCEPT /* Only use libintercept in combination with native runtime! */ if (config.use_libintercept) { - shim_set_audit_path(); + shim_set_audit_path(operation_prefix); } #endif #ifdef HAVE_LIBREDIRECT /* Only use libredirect in combination with native runtime! */ if (config.use_libredirect) { - shim_set_ld_preload(); + shim_set_ld_preload(operation_prefix); } #endif } else { /* Only preload when needed. */ if (lsi_system_requires_preload()) { - setenv("LD_PRELOAD", lsi_preload_list(), 1); + shim_export_merge_vars("LD_PRELOAD", operation_prefix, lsi_preload_list()); } setenv("STEAM_RUNTIME", "1", 1); }