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); }