mirror of
https://github.com/yuzu-emu/AppImageKit-checkrt.git
synced 2025-02-02 01:41:11 +00:00
load exec() wrapper if optional runtimes are present
This commit is contained in:
parent
2b645a7f55
commit
bce42d0560
|
@ -1,19 +1,34 @@
|
||||||
|
https://github.com/AppImage/AppImageKit/blob/ddcb5b98073ec251cbddda7a4eaa17545f06bbff/AppRun.c
|
||||||
|
|
||||||
--- a/AppRun.c
|
--- a/AppRun.c
|
||||||
+++ b/AppRun.c
|
+++ b/AppRun.c
|
||||||
@@ -156,6 +156,7 @@
|
@@ -164,6 +164,10 @@
|
||||||
char *old_env;
|
char *old_env;
|
||||||
const int length = 2047;
|
size_t length;
|
||||||
char new_env[8][length+1];
|
const char *format;
|
||||||
+ checkrt(usr_in_appdir);
|
+ checkrt(usr_in_appdir);
|
||||||
|
+
|
||||||
|
+ if (optional_ld_preload)
|
||||||
|
+ putenv(optional_ld_preload);
|
||||||
|
|
||||||
/* https://docs.python.org/2/using/cmdline.html#envvar-PYTHONHOME */
|
/* https://docs.python.org/2/using/cmdline.html#envvar-PYTHONHOME */
|
||||||
snprintf(new_env[0], length, "PYTHONHOME=%s/usr/", appdir);
|
SET_NEW_ENV(new_pythonhome, appdir_s, "PYTHONHOME=%s/usr/", appdir);
|
||||||
@@ -164,7 +165,7 @@
|
@@ -172,7 +176,7 @@
|
||||||
snprintf(new_env[1], length, "PATH=%s/usr/bin/:%s/usr/sbin/:%s/usr/games/:%s/bin/:%s/sbin/:%s", appdir, appdir, appdir, appdir, appdir, old_env);
|
SET_NEW_ENV(new_path, appdir_s*5 + strlen(old_env), "PATH=%s/usr/bin/:%s/usr/sbin/:%s/usr/games/:%s/bin/:%s/sbin/:%s", appdir, appdir, appdir, appdir, appdir, old_env);
|
||||||
|
|
||||||
old_env = getenv("LD_LIBRARY_PATH") ?: "";
|
old_env = getenv("LD_LIBRARY_PATH") ?: "";
|
||||||
- snprintf(new_env[2], length, "LD_LIBRARY_PATH=%s/usr/lib/:%s/usr/lib/i386-linux-gnu/:%s/usr/lib/x86_64-linux-gnu/:%s/usr/lib32/:%s/usr/lib64/:%s/lib/:%s/lib/i386-linux-gnu/:%s/lib/x86_64-linux-gnu/:%s/lib32/:%s/lib64/:%s", appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, old_env);
|
- SET_NEW_ENV(new_ld_library_path, appdir_s*10 + strlen(old_env), "LD_LIBRARY_PATH=%s/usr/lib/:%s/usr/lib/i386-linux-gnu/:%s/usr/lib/x86_64-linux-gnu/:%s/usr/lib32/:%s/usr/lib64/:%s/lib/:%s/lib/i386-linux-gnu/:%s/lib/x86_64-linux-gnu/:%s/lib32/:%s/lib64/:%s", appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, old_env);
|
||||||
+ snprintf(new_env[2], length, "LD_LIBRARY_PATH=%s%s/usr/lib/:%s/usr/lib/i386-linux-gnu/:%s/usr/lib/x86_64-linux-gnu/:%s/usr/lib32/:%s/usr/lib64/:%s/lib/:%s/lib/i386-linux-gnu/:%s/lib/x86_64-linux-gnu/:%s/lib32/:%s/lib64/:%s", optional, appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, old_env);
|
+ SET_NEW_ENV(new_ld_library_path, appdir_s*10 + strlen(old_env), "LD_LIBRARY_PATH=%s%s/usr/lib/:%s/usr/lib/i386-linux-gnu/:%s/usr/lib/x86_64-linux-gnu/:%s/usr/lib32/:%s/usr/lib64/:%s/lib/:%s/lib/i386-linux-gnu/:%s/lib/x86_64-linux-gnu/:%s/lib32/:%s/lib64/:%s", optional, appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, appdir, old_env);
|
||||||
|
|
||||||
old_env = getenv("PYTHONPATH") ?: "";
|
old_env = getenv("PYTHONPATH") ?: "";
|
||||||
snprintf(new_env[3], length, "PYTHONPATH=%s/usr/share/pyshared/:%s", appdir, old_env);
|
SET_NEW_ENV(new_pythonpath, appdir_s + strlen(old_env), "PYTHONPATH=%s/usr/share/pyshared/:%s", appdir, old_env);
|
||||||
|
@@ -201,6 +205,9 @@
|
||||||
|
if (ret == -1)
|
||||||
|
die("Error executing '%s': %s\n", exe, strerror(error));
|
||||||
|
|
||||||
|
+ free(optional);
|
||||||
|
+ if (optional_ld_preload)
|
||||||
|
+ free(optional_ld_preload);
|
||||||
|
free(line);
|
||||||
|
free(desktop_file);
|
||||||
|
free(usr_in_appdir);
|
||||||
|
|
12
Makefile
12
Makefile
|
@ -1,16 +1,22 @@
|
||||||
CFLAGS ?= -O2 -Wall -Wextra
|
CFLAGS ?= -O2 -Wall -Wextra
|
||||||
CFLAGS += -include checkrt.h
|
|
||||||
LDFLAGS += -s
|
LDFLAGS += -s
|
||||||
BIN = AppRun_patched
|
BIN = AppRun_patched
|
||||||
|
LIB = exec.so
|
||||||
|
|
||||||
|
|
||||||
all: $(BIN)
|
all: $(BIN) $(LIB)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm -f $(BIN) *.o AppRun.c AppRun_patched.c
|
-rm -f $(BIN) $(LIB) *.o AppRun.c AppRun_patched.c
|
||||||
|
|
||||||
$(BIN): AppRun_patched.o checkrt.o
|
$(BIN): AppRun_patched.o checkrt.o
|
||||||
|
|
||||||
|
$(LIB): exec.o
|
||||||
|
$(CC) -shared $(LDFLAGS) -o $@ $^ -ldl
|
||||||
|
|
||||||
|
AppRun_patched.o checkrt.o: CFLAGS += -include checkrt.h
|
||||||
|
exec.o: CFLAGS += -fPIC
|
||||||
|
|
||||||
AppRun_patched.c: AppRun.c
|
AppRun_patched.c: AppRun.c
|
||||||
patch -p1 --output $@ < AppRun.c.patch
|
patch -p1 --output $@ < AppRun.c.patch
|
||||||
|
|
||||||
|
|
|
@ -15,5 +15,5 @@ That's because both libraries are part of GCC.
|
||||||
You would have to know the library version of the host system and decide whether to use a bundled library or not before the
|
You would have to know the library version of the host system and decide whether to use a bundled library or not before the
|
||||||
application is started. This is exactly what the patched AppRun binary does.
|
application is started. This is exactly what the patched AppRun binary does.
|
||||||
It will search for `usr/optional/libstdc++/libstdc++.so.6` and `usr/optional/libgcc_s/libgcc_s.so.1` inside the AppImage or AppDir.
|
It will search for `usr/optional/libstdc++/libstdc++.so.6` and `usr/optional/libgcc_s/libgcc_s.so.1` inside the AppImage or AppDir.
|
||||||
If found it will compare their internal versions with the ones found on the system and prepend their paths to `LD_LIBRARY_PATH`
|
If found it will compare their internal versions with the ones found on the system and prepend their paths to `LD_LIBRARY_PATH` if necessary.
|
||||||
if necessary.
|
You should also put `exec.so` into `usr/optional`.
|
||||||
|
|
18
checkrt.c
18
checkrt.c
|
@ -41,10 +41,12 @@
|
||||||
ret = fscanf(f, "%s", sym); (void)ret; \
|
ret = fscanf(f, "%s", sym); (void)ret; \
|
||||||
pclose(f);
|
pclose(f);
|
||||||
|
|
||||||
#define CXXDIR "optional/libstdc++"
|
#define CXXDIR "optional/libstdc++"
|
||||||
#define GCCDIR "optional/libgcc"
|
#define GCCDIR "optional/libgcc"
|
||||||
|
#define EXEC_SO "optional/exec.so"
|
||||||
|
|
||||||
char optional[1024];
|
char *optional = NULL;
|
||||||
|
char *optional_ld_preload = NULL;
|
||||||
|
|
||||||
void checkrt(char *usr_in_appdir)
|
void checkrt(char *usr_in_appdir)
|
||||||
{
|
{
|
||||||
|
@ -92,6 +94,7 @@ void checkrt(char *usr_in_appdir)
|
||||||
|
|
||||||
int bundle_cxx = 0;
|
int bundle_cxx = 0;
|
||||||
int bundle_gcc = 0;
|
int bundle_gcc = 0;
|
||||||
|
size_t len = strlen(usr_in_appdir);
|
||||||
|
|
||||||
if (stdcxx_bundle_ver > stdcxx_sys_ver)
|
if (stdcxx_bundle_ver > stdcxx_sys_ver)
|
||||||
bundle_cxx = 1;
|
bundle_cxx = 1;
|
||||||
|
@ -99,13 +102,22 @@ void checkrt(char *usr_in_appdir)
|
||||||
if (gcc_bundle_ver > gcc_sys_ver)
|
if (gcc_bundle_ver > gcc_sys_ver)
|
||||||
bundle_gcc = 1;
|
bundle_gcc = 1;
|
||||||
|
|
||||||
|
if (bundle_cxx == 1 || bundle_gcc == 1) {
|
||||||
|
optional_ld_preload = malloc(strlen("LD_PRELOAD=") + strlen(EXEC_SO) + 1 + len);
|
||||||
|
sprintf(optional_ld_preload, "LD_PRELOAD=%s/" EXEC_SO, usr_in_appdir);
|
||||||
|
}
|
||||||
|
|
||||||
if (bundle_cxx == 1 && bundle_gcc == 0) {
|
if (bundle_cxx == 1 && bundle_gcc == 0) {
|
||||||
|
optional = malloc(strlen(CXXDIR) + 2 + len);
|
||||||
sprintf(optional, "%s/" CXXDIR ":", usr_in_appdir);
|
sprintf(optional, "%s/" CXXDIR ":", usr_in_appdir);
|
||||||
} else if (bundle_cxx == 0 && bundle_gcc == 1) {
|
} else if (bundle_cxx == 0 && bundle_gcc == 1) {
|
||||||
|
optional = malloc(strlen(GCCDIR) + 2 + len);
|
||||||
sprintf(optional, "%s/" GCCDIR ":", usr_in_appdir);
|
sprintf(optional, "%s/" GCCDIR ":", usr_in_appdir);
|
||||||
} else if (bundle_cxx == 1 && bundle_gcc == 1) {
|
} else if (bundle_cxx == 1 && bundle_gcc == 1) {
|
||||||
|
optional = malloc(strlen(GCCDIR) + strlen(CXXDIR) + 4 + len*2);
|
||||||
sprintf(optional, "%s/" GCCDIR ":%s/" CXXDIR ":", usr_in_appdir, usr_in_appdir);
|
sprintf(optional, "%s/" GCCDIR ":%s/" CXXDIR ":", usr_in_appdir, usr_in_appdir);
|
||||||
} else {
|
} else {
|
||||||
|
optional = malloc(2);
|
||||||
sprintf(optional, "%s", "");
|
sprintf(optional, "%s", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
extern char optional[1024];
|
extern char *optional;
|
||||||
|
extern char *optional_ld_preload;
|
||||||
extern void checkrt(char *usr_in_appdir);
|
extern void checkrt(char *usr_in_appdir);
|
||||||
|
|
315
exec.c
Normal file
315
exec.c
Normal file
|
@ -0,0 +1,315 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Sven Brauch <mail@svenbrauch.de>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public License
|
||||||
|
* along with this library; see the file COPYING.LIB. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
This library is intended to be used together with the AppImage distribution mechanism.
|
||||||
|
Place the library somewhere in your AppImage and point LD_PRELOAD to it
|
||||||
|
before launching your application.
|
||||||
|
|
||||||
|
Whenever your application invokes a child process through execv() or execve(),
|
||||||
|
this wrapper will intercept the call and see if the child process lies
|
||||||
|
outside of the bundled appdir. If it does, the wrapper will attempt to undo
|
||||||
|
any changes done to environment variables before launching the process,
|
||||||
|
since you probably did not intend to launch it with e.g. the LD_LIBRARY_PATH
|
||||||
|
you previously set for your application.
|
||||||
|
|
||||||
|
To perform this operation, you have to set the following environment variables:
|
||||||
|
$APPDIR -- path of the AppDir you are launching your application from. If this
|
||||||
|
is not present, the wrapper will do nothing.
|
||||||
|
|
||||||
|
For each environment variable you want restored, where {VAR} is the name of the environment
|
||||||
|
variable (e.g. "PATH"):
|
||||||
|
$APPIMAGE_ORIGINAL_{VAR} -- original value of the environment variable
|
||||||
|
$APPIMAGE_STARTUP_{VAR} -- value of the variable when you were starting up
|
||||||
|
your application
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
typedef ssize_t (*execve_func_t)(const char* filename, char* const argv[], char* const envp[]);
|
||||||
|
static execve_func_t old_execve = NULL;
|
||||||
|
|
||||||
|
typedef ssize_t (*execvp_func_t)(const char* filename, char* const argv[]);
|
||||||
|
//static execvp_func_t old_execvp = NULL;
|
||||||
|
|
||||||
|
// TODO implement me: execl, execlp, execle; but it's annoying work and nothing seems to use them
|
||||||
|
// typedef int (*execl_func_t)(const char *path, const char *arg);
|
||||||
|
// static execl_func_t old_execl = NULL;
|
||||||
|
//
|
||||||
|
// typedef int (*execlp_func_t)(const char *file, const char *arg);
|
||||||
|
// static execlp_func_t old_execlp = NULL;
|
||||||
|
//
|
||||||
|
// typedef int (*execle_func_t)(const char *path, const char *arg, char * const envp[]);
|
||||||
|
// static execle_func_t old_execle = NULL;
|
||||||
|
|
||||||
|
typedef int (*execv_func_t)(const char *path, char *const argv[]);
|
||||||
|
//static execv_func_t old_execv = NULL;
|
||||||
|
|
||||||
|
typedef int (*execvpe_func_t)(const char *file, char *const argv[], char *const envp[]);
|
||||||
|
static execvpe_func_t old_execvpe = NULL;
|
||||||
|
|
||||||
|
char* APPIMAGE_ORIG_PREFIX = "APPIMAGE_ORIGINAL_";
|
||||||
|
char* APPIMAGE_STARTUP_PREFIX = "APPIMAGE_STARTUP_";
|
||||||
|
char* APPDIR = "APPDIR";
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char** names;
|
||||||
|
char** values;
|
||||||
|
} environment;
|
||||||
|
|
||||||
|
environment environment_alloc(size_t envc) {
|
||||||
|
environment env;
|
||||||
|
env.names = calloc(envc+1, sizeof(char*));
|
||||||
|
env.values = calloc(envc+1, sizeof(char*));
|
||||||
|
return env;
|
||||||
|
}
|
||||||
|
|
||||||
|
int arr_len(char* const x[]) {
|
||||||
|
int len = 0;
|
||||||
|
while ( x[len] != 0 ) {
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stringlist_free(char* const envp[]) {
|
||||||
|
if ( envp ) {
|
||||||
|
for ( int i = 0; i < arr_len(envp); i++ ) {
|
||||||
|
free(envp[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char** stringlist_alloc(int size) {
|
||||||
|
char** ret = calloc(size, sizeof(char*));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int environment_len(const environment env) {
|
||||||
|
return arr_len(env.names);
|
||||||
|
}
|
||||||
|
|
||||||
|
void environment_free(environment env) {
|
||||||
|
stringlist_free(env.names);
|
||||||
|
stringlist_free(env.values);
|
||||||
|
}
|
||||||
|
|
||||||
|
void environment_append_item(environment env, char* name, int name_size, char* val, int val_size) {
|
||||||
|
int count = environment_len(env);
|
||||||
|
env.names[count] = calloc(name_size+1, sizeof(char));
|
||||||
|
env.values[count] = calloc(val_size+1, sizeof(char));
|
||||||
|
strncpy(env.names[count], name, name_size);
|
||||||
|
strncpy(env.values[count], val, val_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int environment_find_name(environment env, char* name, int name_size) {
|
||||||
|
int count = environment_len(env);
|
||||||
|
for ( int i = 0; i < count; i++ ) {
|
||||||
|
if ( !strncmp(env.names[i], name, name_size) ) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char** environment_to_stringlist(environment env) {
|
||||||
|
int len = environment_len(env);
|
||||||
|
char** ret = stringlist_alloc(len+1);
|
||||||
|
for ( int i = 0; i < len; i++ ) {
|
||||||
|
char* name = env.names[i];
|
||||||
|
char* value = env.values[i];
|
||||||
|
int result_len = strlen(name) + strlen(value) + 1;
|
||||||
|
ret[i] = calloc(result_len+1, sizeof(char));
|
||||||
|
strcat(ret[i], name);
|
||||||
|
strcat(ret[i], "=");
|
||||||
|
strcat(ret[i], value);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
char** adjusted_environment(const char* filename, char* const envp[]) {
|
||||||
|
if ( !envp ) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int envc = arr_len(envp);
|
||||||
|
|
||||||
|
char* appdir = NULL;
|
||||||
|
|
||||||
|
environment orig = environment_alloc(envc);
|
||||||
|
environment startup = environment_alloc(envc);
|
||||||
|
int orig_prefix_len = strlen(APPIMAGE_ORIG_PREFIX);
|
||||||
|
int startup_prefix_len = strlen(APPIMAGE_STARTUP_PREFIX);
|
||||||
|
for ( int i = 0; i < envc; i++ ) {
|
||||||
|
char* line = envp[i];
|
||||||
|
int name_size = strchr(line, '=')-line;
|
||||||
|
int val_size = strlen(line)-name_size-1;
|
||||||
|
|
||||||
|
if ( !strncmp(line, APPIMAGE_ORIG_PREFIX, orig_prefix_len) ) {
|
||||||
|
environment_append_item(orig, line+orig_prefix_len, name_size-orig_prefix_len,
|
||||||
|
line+name_size+1, val_size);
|
||||||
|
}
|
||||||
|
if ( !strncmp(line, APPIMAGE_STARTUP_PREFIX, startup_prefix_len) ) {
|
||||||
|
environment_append_item(startup, line+startup_prefix_len, name_size-startup_prefix_len,
|
||||||
|
line+name_size+1, val_size);
|
||||||
|
}
|
||||||
|
if ( !strncmp(line, APPDIR, strlen(APPDIR)) ) {
|
||||||
|
appdir = calloc(val_size+1, sizeof(char));
|
||||||
|
strncpy(appdir, line+name_size+1, val_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
environment new_env = environment_alloc(envc);
|
||||||
|
if ( appdir && strncmp(filename, appdir, strlen(appdir)) ) {
|
||||||
|
// we have a value for $APPDIR and are leaving it -- perform replacement
|
||||||
|
for ( int i = 0; i < envc; i++ ) {
|
||||||
|
char* line = envp[i];
|
||||||
|
if ( !strncmp(line, APPIMAGE_ORIG_PREFIX, strlen(APPIMAGE_ORIG_PREFIX)) ||
|
||||||
|
!strncmp(line, APPIMAGE_STARTUP_PREFIX, strlen(APPIMAGE_STARTUP_PREFIX)) )
|
||||||
|
{
|
||||||
|
// we are not interested in the backup vars here, don't copy them over
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int name_size = strchr(line, '=')-line;
|
||||||
|
int val_size = strlen(line)-name_size-1;
|
||||||
|
char* value = line+name_size+1;
|
||||||
|
int value_len = strlen(value);
|
||||||
|
|
||||||
|
int at_startup = environment_find_name(startup, line, name_size);
|
||||||
|
int at_original = environment_find_name(orig, line, name_size);
|
||||||
|
if ( at_startup == -1 || at_original == -1 ) {
|
||||||
|
// no information, just keep it
|
||||||
|
environment_append_item(new_env, line, name_size, value, value_len);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* at_start = startup.values[at_startup];
|
||||||
|
int at_start_len = strlen(at_start);
|
||||||
|
char* at_orig = orig.values[at_original];
|
||||||
|
int at_orig_len = strlen(at_orig);
|
||||||
|
|
||||||
|
// TODO HACK: do not copy over empty vars
|
||||||
|
if ( strlen(at_orig) == 0 ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !strncmp(line+name_size+1, startup.values[at_startup], val_size) ) {
|
||||||
|
// nothing changed since startup, restore old value
|
||||||
|
environment_append_item(new_env, line, name_size, at_orig, at_orig_len);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int chars_added = value_len > at_start_len;
|
||||||
|
char* use_value = NULL;
|
||||||
|
if ( chars_added > 0 ) {
|
||||||
|
// something was added to the current value
|
||||||
|
// take _original_ value of the env var and append/prepend the same thing
|
||||||
|
use_value = calloc(strlen(at_orig) + chars_added + 1, sizeof(char));
|
||||||
|
if ( !strncmp(value, at_start, at_start_len) ) {
|
||||||
|
// append case
|
||||||
|
strcat(use_value, value);
|
||||||
|
strcat(use_value, at_orig + strlen(value));
|
||||||
|
}
|
||||||
|
else if ( !strncmp(value+(value_len-at_start_len), at_start, at_start_len) ) {
|
||||||
|
// prepend case
|
||||||
|
strcat(use_value, at_orig + strlen(value));
|
||||||
|
strcat(use_value, value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// none of the above methods matched
|
||||||
|
// assume the value changed completely and simply keep what the application set
|
||||||
|
free(use_value);
|
||||||
|
use_value = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !use_value ) {
|
||||||
|
environment_append_item(new_env, line, name_size, value, value_len);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
environment_append_item(new_env, line, name_size, use_value, strlen(use_value));
|
||||||
|
free(use_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char** ret = NULL;
|
||||||
|
if ( environment_len(new_env) > 0 ) {
|
||||||
|
ret = environment_to_stringlist(new_env);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// nothing changed
|
||||||
|
ret = stringlist_alloc(envc+1);
|
||||||
|
for ( int i = 0; i < envc; i++ ) {
|
||||||
|
int len = strlen(envp[i]);
|
||||||
|
ret[i] = calloc(len+1, sizeof(char));
|
||||||
|
strncpy(ret[i], envp[i], len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
environment_free(orig);
|
||||||
|
environment_free(startup);
|
||||||
|
environment_free(new_env);
|
||||||
|
free(appdir);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int execve(const char* filename, char* const argv[], char* const envp[]) {
|
||||||
|
char** new_envp = adjusted_environment(filename, envp);
|
||||||
|
old_execve = dlsym(RTLD_NEXT, "execve");
|
||||||
|
int ret = old_execve(filename, argv, new_envp);
|
||||||
|
stringlist_free(new_envp);
|
||||||
|
//printf(">>> custom execve()!\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int execv(const char* filename, char* const argv[]) {
|
||||||
|
char** new_envp = adjusted_environment(filename, environ);
|
||||||
|
old_execve = dlsym(RTLD_NEXT, "execve");
|
||||||
|
int ret = old_execve(filename, argv, new_envp);
|
||||||
|
stringlist_free(new_envp);
|
||||||
|
//printf(">>> custom execv()!\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int execvpe(const char* filename, char* const argv[], char* const envp[]) {
|
||||||
|
// TODO: might not be full path
|
||||||
|
char** new_envp = adjusted_environment(filename, envp);
|
||||||
|
old_execvpe = dlsym(RTLD_NEXT, "execvpe");
|
||||||
|
int ret = old_execvpe(filename, argv, new_envp);
|
||||||
|
stringlist_free(new_envp);
|
||||||
|
//printf(">>> custom execvpe()!\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int execvp(const char* filename, char* const argv[]) {
|
||||||
|
// TODO: might not be full path
|
||||||
|
char** new_envp = adjusted_environment(filename, environ);
|
||||||
|
old_execvpe = dlsym(RTLD_NEXT, "execvpe");
|
||||||
|
int ret = old_execvpe(filename, argv, new_envp);
|
||||||
|
stringlist_free(new_envp);
|
||||||
|
//printf(">>> custom execvp()!\n");
|
||||||
|
return ret;
|
||||||
|
}
|
Loading…
Reference in a new issue