shim: Split majority of the code into shim.c

This helps separate the main launch entry from the bulk of the bootstrap
code, and will also allow us to build a new lsi-exec tool that will just
execute whatever you tell it to, with the full shim setup routine.

Signed-off-by: Ikey Doherty <ikey@solus-project.com>
This commit is contained in:
Ikey Doherty
2017-11-14 21:53:18 +00:00
parent 05bd0e0dac
commit 5013e0d747
4 changed files with 155 additions and 48 deletions
+71
View File
@@ -0,0 +1,71 @@
/*
* This file is part of linux-steam-integration.
*
* Copyright © 2016-2017 Ikey Doherty <ikey@solus-project.com>
*
* linux-steam-integration is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*/
#define _GNU_SOURCE
#include <linux/limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../common/files.h"
#include "lsi.h"
#include "shim.h"
/**
* Helper to get the Steam binary, respecting "$SNAP" if needed
*/
static const char *shim_get_steam_binary(const char *prefix)
{
static char tgt[PATH_MAX] = { 0 };
if (snprintf(tgt, sizeof(tgt), "%s%s", prefix ? prefix : "", STEAM_BINARY) < 0) {
return STEAM_BINARY;
}
return tgt;
}
int main(int argc, char **argv)
{
const char *operation_prefix = NULL;
const char *steam_binary = NULL;
if (!shim_bootstrap()) {
return EXIT_FAILURE;
}
#ifdef HAVE_SNAPD_SUPPORT
operation_prefix = getenv("SNAP");
#endif
steam_binary = shim_get_steam_binary(operation_prefix);
if (!lsi_file_exists(steam_binary)) {
lsi_report_failure("Steam isn't currently installed at %s", steam_binary);
return EXIT_FAILURE;
}
return shim_execute(steam_binary, --argc, ++argv);
}
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=8 tabstop=8 expandtab:
* :indentSize=8:tabSize=8:noTabs=true:
*/
+1
View File
@@ -7,6 +7,7 @@ endif
if shim_behaviour != 'none'
shim_sources = [
'shim.c',
'main.c',
]
shim = executable(
+43 -48
View File
@@ -24,6 +24,7 @@
#include "../nica/files.h"
#include "config.h"
#include "lsi.h"
#include "shim.h"
/**
* Required to force Steam into 32-bit detection mode, which is useful for
@@ -96,20 +97,6 @@ static void shim_set_ld_preload(const char *prefix)
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(const char *prefix)
{
static char tgt[PATH_MAX] = { 0 };
if (snprintf(tgt, sizeof(tgt), "%s%s", prefix ? prefix : "", STEAM_BINARY) < 0) {
return STEAM_BINARY;
}
return tgt;
}
#ifdef HAVE_SNAPD_SUPPORT
/**
* This function is only used during our initial bootstrap phase to ensure
@@ -281,53 +268,42 @@ static void shim_export_extra(__lsi_unused__ const char *prefix)
}
#endif
int main(int argc, char **argv)
static LsiConfig lsi_config = { 0 };
/* Public API */
bool shim_bootstrap()
{
LsiConfig config = { 0 };
bool is_x86_64;
const char *n_argv[argc + 2];
const char *exec_command = NULL;
/* Use the appropriate Steam depending on configuration */
const char *lsi_exec_bin = NULL;
int i = 1;
int8_t off = 0;
int (*vfunc)(const char *, char *const argv[]) = NULL;
const char *operation_prefix = NULL;
#ifdef HAVE_SNAPD_SUPPORT
/* Snapd specific prefix */
operation_prefix = getenv("SNAP");
#endif
lsi_exec_bin = shim_get_steam_binary(operation_prefix);
/* Initialise config */
if (!lsi_config_load(&config)) {
lsi_config_load_defaults(&config);
/* Ensure we now have some kind of config */
if (!lsi_config_load(&lsi_config)) {
lsi_config_load_defaults(&lsi_config);
}
is_x86_64 = lsi_system_is_64bit();
if (!lsi_file_exists(lsi_exec_bin)) {
lsi_report_failure("Steam isn't currently installed at %s", lsi_exec_bin);
return EXIT_FAILURE;
}
errno = 0;
/* We might have additional variables we need to export */
shim_export_extra(operation_prefix);
/* Force STEAM_RUNTIME into the environment */
if (config.use_native_runtime) {
if (lsi_config.use_native_runtime) {
/* Explicitly disable the runtime */
setenv("STEAM_RUNTIME", "0", 1);
#ifdef HAVE_LIBINTERCEPT
/* Only use libintercept in combination with native runtime! */
if (config.use_libintercept) {
if (lsi_config.use_libintercept) {
shim_set_audit_path(operation_prefix);
}
#endif
#ifdef HAVE_LIBREDIRECT
/* Only use libredirect in combination with native runtime! */
if (config.use_libredirect) {
if (lsi_config.use_libredirect) {
shim_set_ld_preload(operation_prefix);
}
#endif
@@ -353,37 +329,56 @@ int main(int argc, char **argv)
unsetenv("XMODIFIERS");
unsetenv("GTK_MODULES");
memset(&n_argv, 0, sizeof(char *) * (argc + 2));
if (errno != 0) {
lsi_report_failure("Failed to bootstrap LSI: %s", strerror(errno));
return false;
}
/* All done now. */
return true;
}
int shim_execute(const char *command, int argc, char **argv)
{
bool is_x86_64;
const char *n_argv[argc + 3];
const char *exec_command = NULL;
int i = 1;
int8_t off = 1;
int (*vfunc)(const char *, char *const argv[]) = NULL;
is_x86_64 = lsi_system_is_64bit();
memset(&n_argv, 0, sizeof(char *) * (argc + 3));
/* If we're 64-bit and 32-bit is forced, proxy via linux32 */
if (config.force_32 && is_x86_64) {
if (lsi_config.force_32 && is_x86_64) {
exec_command = EMUL32BIN;
n_argv[0] = EMUL32BIN;
n_argv[1] = lsi_exec_bin;
off = 1;
n_argv[1] = command;
off = 2;
/* Use linux32 in the path */
vfunc = execvp;
} else {
/* Directly call lsi_exec_bin */
exec_command = lsi_exec_bin;
n_argv[0] = lsi_exec_bin;
exec_command = command;
n_argv[0] = command;
/* Full path here due to shadow nature */
vfunc = execv;
}
/* Point arguments to arguments passed to us */
for (i = 1; i < argc; i++) {
for (i = 0; i < argc; i++) {
n_argv[i + off] = argv[i];
}
n_argv[i + 1 + off] = NULL;
/* Go execute steam. */
if (vfunc(exec_command, (char **)n_argv) < 0) {
lsi_report_failure("Failed to launch Steam: %s [%s]",
strerror(errno),
lsi_exec_bin);
lsi_report_failure("Failed to launch command: %s [%s]", strerror(errno), command);
return EXIT_FAILURE;
}
/* Can't happen */
return EXIT_FAILURE;
}
/*
+40
View File
@@ -0,0 +1,40 @@
/*
* This file is part of linux-steam-integration.
*
* Copyright © 2016-2017 Ikey Doherty <ikey@solus-project.com>
*
* linux-steam-integration is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*/
#define _GNU_SOURCE
#include <stdbool.h>
/**
* Attempt to bootstrap the shim environment prior to execution of
* a command.
*/
bool shim_bootstrap(void);
/**
* Execute the given command
*
* @note If this succeeds, we will not return
*/
int shim_execute(const char *command, int argc, char **argv);
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=8 tabstop=8 expandtab:
* :indentSize=8:tabSize=8:noTabs=true:
*/