File eclipse-launcher-link.patch of Package eclipse
Index: eclipseGtk.c
===================================================================
RCS file: /cvsroot/eclipse/platform-launcher/library/gtk/eclipseGtk.c,v
retrieving revision 1.25
diff -u -r1.25 eclipseGtk.c
--- platform-launcher/library/gtk/eclipseGtk.c 17 Sep 2005 03:39:24 -0000 1.25
+++ platform-launcher/library/gtk/eclipseGtk.c 3 Feb 2006 17:05:29 -0000
@@ -28,6 +28,7 @@
#include <stdlib.h>
#include <string.h>
#include <locale.h>
+#include <limits.h>
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
@@ -292,6 +293,159 @@
}
+/* 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 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[])
+{
+ 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 */
+
+ link = (char *) malloc(sizeof(char) * PATH_MAX);
+
+ linkpath = (char *) malloc(sizeof(char) * PATH_MAX);
+
+ /* 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;
+ }
+
+ 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;
+ }
+ }
+ }
+ }
+ }
+}
+
+
/* Start the Java VM
*
* This method is called to start the Java virtual machine and to wait until it
@@ -302,11 +456,16 @@
int jvmExitCode = 1;
pid_t jvmProcess;
int exitCode;
-
+
#ifdef MOZILLA_FIX
fixEnvForMozilla();
#endif /* MOZILLA_FIX */
+
+ /* Change the paths if we are running through a symlink */
+ changeArgPaths(args);
+
+
jvmProcess = fork();
if (jvmProcess == 0)
{