mirror of
https://github.com/clearlinux/linux-steam-integration.git
synced 2026-09-06 22:01:27 +00:00
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:
@@ -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:
|
||||
*/
|
||||
@@ -7,6 +7,7 @@ endif
|
||||
if shim_behaviour != 'none'
|
||||
shim_sources = [
|
||||
'shim.c',
|
||||
'main.c',
|
||||
]
|
||||
|
||||
shim = executable(
|
||||
|
||||
+43
-48
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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:
|
||||
*/
|
||||
Reference in New Issue
Block a user