|
|
#include <stdlib.h> | #include <stdlib.h> |
#include <string.h> | #include <string.h> |
#include <locale.h> | #include <locale.h> |
|
#include <limits.h> |
| |
#include <gtk/gtk.h> | #include <gtk/gtk.h> |
#include <gdk-pixbuf/gdk-pixbuf.h> | #include <gdk-pixbuf/gdk-pixbuf.h> |
|
|
return result; | return result; |
} | } |
| |
|
/* represents a linked list of used memory blocks, used for the arguments |
|
* swapping below, so that we don't leak memory */ |
|
struct llist |
|
{ |
|
char * data; |
|
struct llist * next; |
|
}; |
|
|
|
/* We check to see if the launcher was run from a symlink, if it was |
|
* we need to change some paths to point at the actual launcher path, |
|
* not the symlink-relative path. |
|
* |
|
* This works as follows: |
|
* |
|
* The symlink is usually something in /usr/bin (i.e. /usr/bin/eclipse) and |
|
* links to something in /usr/share/<eclipse-install-dir> |
|
* (i.e. /usr/share/eclipse/eclipse). However since the share dir should not |
|
* have a compiled code in it, we store the actual launcher in |
|
* /usr/lib/<eclipse-install-dir>/ (i.e. /usr/lib/eclipse/eclipse). |
|
* |
|
* But startup.jar is in /usr/share/<eclipse-install-dir> so we need to make |
|
* the launcher resolve one link deep and get the startup.jar at that path. |
|
*/ |
|
int changeArgPaths(char *args[], struct llist ** toFree) |
|
{ |
|
int ret, pathlen, jarlen; |
|
struct stat st; |
|
char * link, * linkpath; |
|
char ** opt, *tmp_p, *jarPath; |
|
int launcherPos = 0; |
|
int foundLauncher = 0; /* is the next arg supposed to be -launcher */ |
|
int prevWasJar = 0; /* is the next arg supposed to be -jar */ |
|
struct llist * curMemblock; |
|
|
|
*toFree = (struct llist *) malloc(sizeof (struct llist)); |
|
link = (char *) malloc(sizeof(char) * PATH_MAX); |
|
(*toFree)->data = link; |
|
|
|
(*toFree)->next = (struct llist *) malloc(sizeof (struct llist)); |
|
curMemblock = (*toFree)->next; |
|
|
|
linkpath = (char *) malloc(sizeof(char) * PATH_MAX); |
|
curMemblock->data = linkpath; |
|
|
|
/* first find the path of the launcher, this is after the -launcher |
|
* command line option */ |
|
|
|
for (opt = args; *opt != NULL; opt++) |
|
{ |
|
/* we found the '-launcher' flag */ |
|
if (!strncmp(*opt, "-launcher", PATH_MAX -1)) |
|
{ |
|
foundLauncher = 1; |
|
} |
|
|
|
/* the flag after '-launcher' was not another '-blah' */ |
|
if (foundLauncher == 1 && **opt != '-') |
|
{ |
|
foundLauncher = 2; |
|
launcherPos = opt - args; |
|
break; |
|
} |
|
} |
|
|
|
/* see if we found the launcher path argument, otherwise, we'll just |
|
* fail later */ |
|
if (launcherPos > 0) |
|
{ |
|
/* fix the executable name if we are running through a link */ |
|
ret = lstat(args[launcherPos], &st); |
|
if ( ret < 0 ) |
|
{ |
|
printf("Lstat returned(%d): %s\n:", errno, strerror(errno)); |
|
return ret; |
|
} |
|
|
|
if (S_ISLNK(st.st_mode)) |
|
{ |
|
/* read one link deep */ |
|
ret = readlink(args[launcherPos], link, PATH_MAX - 1); |
|
if (ret < 0) |
|
{ |
|
printf("Readlink returned(%d): %s\n:", errno, strerror(errno)); |
|
return ret; |
|
} |
|
|
|
/* null terminate, since readlink() doesn't do that */ |
|
link[ret] = '\0'; |
|
|
|
/* replace the name of the program */ |
|
args[launcherPos] = link; |
|
strncpy(linkpath, link, PATH_MAX); |
|
|
|
|
|
/* now we need to replace every occurence of |
|
* -jar <somejar> with |
|
* -jar <path_to_dereferenced_link>/<somejar> |
|
* but only if the jar was not specified with an absolute path. |
|
* |
|
* We search the args for -jar, and see if they are aboslute, if not |
|
* we prepend the path. |
|
*/ |
|
|
|
/* first find the path of the given launcher (before the last '/') */ |
|
tmp_p = strrchr(linkpath, '/'); |
|
|
|
/* if the linked launcher is not a relative path to a file in the |
|
* current directory */ |
|
if (tmp_p != NULL) |
|
{ |
|
/* truncate the after the last directory, keeping the '/' */ |
|
tmp_p++; |
|
*tmp_p = '\0'; |
|
|
|
pathlen = strlen(linkpath); |
|
|
|
for (opt = args; *opt != NULL; opt++) |
|
{ |
|
/* we found a '-jar' flag, set for next iteration */ |
|
if (!strncmp(*opt, "-jar", PATH_MAX -1)) |
|
{ |
|
prevWasJar = 1; |
|
} |
|
|
|
/* if we're at the argument after a 'jar' and it's not another |
|
* '-blah' */ |
|
if (prevWasJar == 1 && **opt != '-') |
|
{ |
|
/* if the jar is an absolute path we won't do anything to |
|
* it, because we assume it's correct */ |
|
if ( **opt == '/') |
|
{ |
|
continue; |
|
} |
|
|
|
jarlen = strlen(*opt); |
|
|
|
/* we know that the jar is a relative path, so we just |
|
* prepend it with the path to the link's target */ |
|
|
|
jarPath = (char *) malloc (sizeof(char) * |
|
(pathlen + jarlen + 1)); |
|
if (jarPath == NULL) |
|
{ |
|
printf("Could not allocate a jar path, die...\n"); |
|
return ENOMEM; |
|
} |
|
|
|
/* add this malloced memory to the list */ |
|
curMemblock->next = (struct llist *) malloc |
|
(sizeof (struct llist)); |
|
curMemblock = curMemblock->next; |
|
curMemblock->data = jarPath; |
|
|
|
strncpy(jarPath, linkpath, pathlen + 1); |
|
strncat(jarPath, *opt, jarlen); |
|
|
|
/* replace the jar with a pathed jar */ |
|
*opt = jarPath; |
|
} |
|
|
|
/* if we're not in at the -jar argument anymore, reset the |
|
* flag */ |
|
if (strncmp(*opt, "-jar", PATH_MAX -1)) |
|
{ |
|
prevWasJar = 0; |
|
} |
|
} |
|
} |
|
} |
|
curMemblock->next = NULL; |
|
|
|
} |
|
} |
|
|
|
/* frees a linked list and it's data */ |
|
void freeMem(struct llist * toFree) |
|
{ |
|
struct llist * next; |
|
while (toFree != NULL) |
|
{ |
|
next = toFree->next; |
|
if (toFree->data != NULL) |
|
free(toFree->data); |
|
free(toFree); |
|
toFree = next; |
|
} |
|
} |
| |
/* Start the Java VM | /* Start the Java VM |
* | * |
|
|
int jvmExitCode = 1; | int jvmExitCode = 1; |
pid_t jvmProcess; | pid_t jvmProcess; |
int exitCode; | int exitCode; |
|
struct llist * toFree; /* memory used for symlink path changing */ |
|
|
#ifdef MOZILLA_FIX | #ifdef MOZILLA_FIX |
fixEnvForMozilla(); | fixEnvForMozilla(); |
#endif /* MOZILLA_FIX */ | #endif /* MOZILLA_FIX */ |
| |
|
|
|
/* Change the paths if we are running through a symlink */ |
|
changeArgPaths(args, &toFree); |
|
|
|
|
jvmProcess = fork(); | jvmProcess = fork(); |
if (jvmProcess == 0) | if (jvmProcess == 0) |
{ | { |
|
|
jvmExitCode = WEXITSTATUS(exitCode); | jvmExitCode = WEXITSTATUS(exitCode); |
} | } |
| |
|
/* We currently don't free the memory we allocated because it might be |
|
* reused if the workspace is restarted (i.e. after an Update Manager |
|
* installation). So we leave the memory alone, it will be freed when |
|
* this process completely exits, this is OK because it needs to stay |
|
* around for the lifetime of the process in any case. */ |
|
/* freeMem(toFree); */ |
|
|
return jvmExitCode; | return jvmExitCode; |
} | } |
| |