Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: Always use link target for /proc/self/exe #1168

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 38 additions & 51 deletions src/runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ mkdir_p(const char* const path)
}

void
print_help(const char *appimage_path)
print_help(const char *appimage_fullpath)
{
// TODO: "--appimage-list List content from embedded filesystem image\n"
fprintf(stderr,
Expand Down Expand Up @@ -244,27 +244,19 @@ print_help(const char *appimage_path)
" and is neither moved nor renamed, the application contained inside this\n"
" AppImage to store its data in this directory rather than in your home\n"
" directory\n"
, appimage_path);
, appimage_fullpath);
}

void
portable_option(const char *arg, const char *appimage_path, const char *name)
portable_option(const char *arg, const char *appimage_fullpath, const char *name)
s-zeid marked this conversation as resolved.
Show resolved Hide resolved
{
char option[32];
sprintf(option, "appimage-portable-%s", name);

if (arg && strcmp(arg, option)==0) {
char portable_dir[PATH_MAX];
char fullpath[PATH_MAX];

ssize_t length = readlink(appimage_path, fullpath, sizeof(fullpath));
if (length < 0) {
fprintf(stderr, "Error getting realpath for %s\n", appimage_path);
exit(EXIT_FAILURE);
}
fullpath[length] = '\0';

sprintf(portable_dir, "%s.%s", fullpath, name);
sprintf(portable_dir, "%s.%s", appimage_fullpath, name);
if (!mkdir(portable_dir, S_IRWXU))
fprintf(stderr, "Portable %s directory created at %s\n", name, portable_dir);
else
Expand Down Expand Up @@ -536,7 +528,15 @@ int main(int argc, char *argv[]) {
* functionality specifically for builds used by appimaged.
*/
if (getenv("TARGET_APPIMAGE") == NULL) {
strcpy(appimage_path, "/proc/self/exe");
// for some reason, `fopen("/proc/self/exe", "rb")` tries to open
// the dynamic linker when running under gcompat, even though `readlink()`
// gives the right result, so use `readlink()` here
ssize_t len = readlink("/proc/self/exe", appimage_path, sizeof(appimage_path));
TheAssassin marked this conversation as resolved.
Show resolved Hide resolved
if (len < 0) {
TheAssassin marked this conversation as resolved.
Show resolved Hide resolved
perror("Failed to obtain AppImage path");
exit(EXIT_EXECERROR);
}
appimage_path[len] = '\0';
strcpy(argv0_path, argv[0]);
} else {
strcpy(appimage_path, getenv("TARGET_APPIMAGE"));
Expand Down Expand Up @@ -577,6 +577,24 @@ int main(int argc, char *argv[]) {
#endif
}

// calculate full path of AppImage
char appimage_fullpath[PATH_MAX];

if(getenv("TARGET_APPIMAGE") == NULL) {
TheAssassin marked this conversation as resolved.
Show resolved Hide resolved
// If we are operating on this file itself, then we've already
// expanded the symlink at `/proc/self/exe` in order to work
// around the issue with gcompat described above
strcpy(appimage_fullpath, appimage_path);
} else {
char* abspath = realpath(appimage_path, NULL);
if (abspath == NULL) {
perror("Failed to obtain realpath for $TARGET_APPIMAGE");
exit(EXIT_EXECERROR);
}
strcpy(appimage_fullpath, abspath);
free(abspath);
}

// temporary directories are required in a few places
// therefore we implement the detection of the temp base dir at the top of the code to avoid redundancy
char temp_base[PATH_MAX] = P_tmpdir;
Expand All @@ -599,16 +617,7 @@ int main(int argc, char *argv[]) {

/* Print the help and then exit */
if(arg && strcmp(arg,"appimage-help")==0) {
char fullpath[PATH_MAX];

ssize_t length = readlink(appimage_path, fullpath, sizeof(fullpath));
if (length < 0) {
fprintf(stderr, "Error getting realpath for %s\n", appimage_path);
exit(EXIT_EXECERROR);
}
fullpath[length] = '\0';

print_help(fullpath);
print_help(appimage_fullpath);
exit(0);
}

Expand Down Expand Up @@ -642,28 +651,6 @@ int main(int argc, char *argv[]) {
exit(0);
}

// calculate full path of AppImage
int length;
char fullpath[PATH_MAX];

if(getenv("TARGET_APPIMAGE") == NULL) {
// If we are operating on this file itself
ssize_t len = readlink(appimage_path, fullpath, sizeof(fullpath));
if (len < 0) {
perror("Failed to obtain absolute path");
exit(EXIT_EXECERROR);
}
fullpath[len] = '\0';
} else {
char* abspath = realpath(appimage_path, NULL);
if (abspath == NULL) {
perror("Failed to obtain absolute path");
exit(EXIT_EXECERROR);
}
strcpy(fullpath, abspath);
free(abspath);
}

if (getenv("APPIMAGE_EXTRACT_AND_RUN") != NULL || (arg && strcmp(arg, "appimage-extract-and-run") == 0)) {
char* hexlified_digest = NULL;

Expand Down Expand Up @@ -727,7 +714,7 @@ int main(int argc, char *argv[]) {
new_argv[new_argc] = NULL;

/* Setting some environment variables that the app "inside" might use */
setenv("APPIMAGE", fullpath, 1);
setenv("APPIMAGE", appimage_fullpath, 1);
setenv("ARGV0", argv0_path, 1);
setenv("APPDIR", prefix, 1);

Expand Down Expand Up @@ -785,8 +772,8 @@ int main(int argc, char *argv[]) {
exit(0);
}

portable_option(arg, appimage_path, "home");
portable_option(arg, appimage_path, "config");
portable_option(arg, appimage_fullpath, "home");
portable_option(arg, appimage_fullpath, "config");

// If there is an argument starting with appimage- (but not appimage-mount which is handled further down)
// then stop here and print an error message
Expand Down Expand Up @@ -908,23 +895,23 @@ int main(int argc, char *argv[]) {
}

/* Setting some environment variables that the app "inside" might use */
setenv( "APPIMAGE", fullpath, 1 );
setenv( "APPIMAGE", appimage_fullpath, 1 );
setenv( "ARGV0", argv0_path, 1 );
setenv( "APPDIR", mount_dir, 1 );

char portable_home_dir[PATH_MAX];
char portable_config_dir[PATH_MAX];

/* If there is a directory with the same name as the AppImage plus ".home", then export $HOME */
strcpy (portable_home_dir, fullpath);
strcpy (portable_home_dir, appimage_fullpath);
strcat (portable_home_dir, ".home");
if(is_writable_directory(portable_home_dir)){
fprintf(stderr, "Setting $HOME to %s\n", portable_home_dir);
setenv("HOME",portable_home_dir,1);
}

/* If there is a directory with the same name as the AppImage plus ".config", then export $XDG_CONFIG_HOME */
strcpy (portable_config_dir, fullpath);
strcpy (portable_config_dir, appimage_fullpath);
strcat (portable_config_dir, ".config");
if(is_writable_directory(portable_config_dir)){
fprintf(stderr, "Setting $XDG_CONFIG_HOME to %s\n", portable_config_dir);
Expand Down