Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Niefer2007-01-16 22:22:51 +0000
committerAndrew Niefer2007-01-16 22:22:51 +0000
commitde9a521a158b9c93f48c593fc7c55739247a9c13 (patch)
treea9d9493c180ad7f6c12d9a301450acb0352c6c92
parentae98f7e7567709aff2e04f0fb01440dfabbac5ec (diff)
downloadrt.equinox.framework-de9a521a158b9c93f48c593fc7c55739247a9c13.tar.gz
rt.equinox.framework-de9a521a158b9c93f48c593fc7c55739247a9c13.tar.xz
rt.equinox.framework-de9a521a158b9c93f48c593fc7c55739247a9c13.zip
changes for bug 168775 & improved error handling on JNI calls
-rw-r--r--bundles/org.eclipse.equinox.executable/library/eclipse.c301
-rw-r--r--bundles/org.eclipse.equinox.executable/library/eclipseJNI.c159
-rw-r--r--bundles/org.eclipse.equinox.executable/library/eclipseJNI.h4
-rw-r--r--bundles/org.eclipse.equinox.executable/library/eclipseMain.c2
-rw-r--r--bundles/org.eclipse.equinox.executable/library/eclipseOS.h4
-rw-r--r--bundles/org.eclipse.equinox.executable/library/eclipseShm.c257
-rw-r--r--bundles/org.eclipse.equinox.executable/library/eclipseShm.h67
-rw-r--r--bundles/org.eclipse.equinox.executable/library/win32/eclipseWin.c88
-rw-r--r--bundles/org.eclipse.equinox.executable/library/win32/make_mingw.mak10
-rw-r--r--bundles/org.eclipse.equinox.executable/library/win32/make_win32.mak10
10 files changed, 745 insertions, 157 deletions
diff --git a/bundles/org.eclipse.equinox.executable/library/eclipse.c b/bundles/org.eclipse.equinox.executable/library/eclipse.c
index aef8b2ca8..c7debe536 100644
--- a/bundles/org.eclipse.equinox.executable/library/eclipse.c
+++ b/bundles/org.eclipse.equinox.executable/library/eclipse.c
@@ -179,6 +179,8 @@
*/
#include "eclipseOS.h"
+#include "eclipseUtil.h"
+#include "eclipseShm.h"
#include "eclipseJNI.h"
#include "eclipseConfig.h"
#include "eclipseCommon.h"
@@ -208,7 +210,9 @@
static _TCHAR* program = NULL; /* full pathname of the program */
static _TCHAR* programDir = NULL; /* directory where program resides */
static _TCHAR* javaVM = NULL; /* full pathname of the Java VM to run */
+static _TCHAR* vmLibrary = NULL; /* full path of a java vm library for JNI invocation */
static _TCHAR* jarFile = NULL; /* full pathname of the startup jar file to run */
+static _TCHAR* sharedID = NULL; /* ID for the shared memory */
_TCHAR* exitData = NULL; /* exit data set from Java */
int initialArgc;
@@ -249,6 +253,7 @@ companion startup.jar file (in the same directory as the executable).");
#define NOSPLASH _T_ECLIPSE("-nosplash")
#define LAUNCHER _T_ECLIPSE("-launcher")
#define SHOWSPLASH _T_ECLIPSE("-showsplash")
+#define EXITDATA _T_ECLIPSE("-exitdata")
#define STARTUP _T_ECLIPSE("-startup")
#define LIBRARY _T_ECLIPSE("-library")
#define VM _T_ECLIPSE("-vm")
@@ -295,15 +300,17 @@ static int optionsSize = (sizeof(options) / sizeof(options[0]));
/* Define the required VM arguments (all platforms). */
static _TCHAR* cp = NULL;
-static _TCHAR** reqVMarg[] = { &cp, NULL }; /* required VM args */
-static _TCHAR** userVMarg = NULL; /* user specific args for the Java VM */
+static _TCHAR* cpValue = NULL;
+static _TCHAR** reqVMarg[] = { &cp, &cpValue, NULL }; /* required VM args */
+static _TCHAR** userVMarg = NULL; /* user specific args for the Java VM */
/* Local methods */
static void parseArgs( int* argc, _TCHAR* argv[] );
static void freeArgList( _TCHAR** data );
static void getVMCommand( int argc, _TCHAR* argv[], _TCHAR **vmArgv[], _TCHAR **progArgv[] );
+static _TCHAR** combineLists( _TCHAR** c1, _TCHAR** c2 );
static _TCHAR** parseArgList( _TCHAR *data );
-static _TCHAR* formatVmCommandMsg( _TCHAR* args[] );
+static _TCHAR* formatVmCommandMsg( _TCHAR* args[], _TCHAR* vmArgs[], _TCHAR* progArgs[] );
static _TCHAR* getDefaultOfficialName();
static _TCHAR* findStartupJar();
static _TCHAR** getRelaunchCommand( _TCHAR **vmCommand );
@@ -333,6 +340,8 @@ JNIEXPORT int run(int argc, _TCHAR* argv[], _TCHAR* vmArgs[])
_TCHAR** relaunchCommand = NULL;
_TCHAR* errorMsg;
int exitCode;
+ int running = 1;
+ int jniLaunching = 1;
/* arg[0] should be the full pathname of this program. */
program = _tcsdup( argv[0] );
@@ -358,10 +367,14 @@ JNIEXPORT int run(int argc, _TCHAR* argv[], _TCHAR* vmArgs[])
exit( 1 );
}
- /* If the user did not specify a VM to be used */
- if (vmName == NULL)
+ if (vmName != NULL) {
+ /* user specified VM */
+ javaVM = findCommand(vmName);
+ jniLaunching = isVMLibrary(javaVM);
+ }
+ else if (vmName == NULL)
{
- /* Determine which type of VM should be used. */
+ /* VM not specified, Determine which type of VM should be used. */
vmName = defaultVM;
/* Try to find the VM shipped with eclipse. */
@@ -384,9 +397,13 @@ JNIEXPORT int run(int argc, _TCHAR* argv[], _TCHAR* vmArgs[])
javaVM = findCommand( vmName );
}
- javaVM = findVMLibrary( javaVM );
+ if(jniLaunching) {
+ vmLibrary = findVMLibrary( javaVM );
+ if(vmLibrary == NULL)
+ jniLaunching = 0;
+ }
/* If the VM was not found, display a message and exit. */
- if (javaVM == NULL)
+ if (!jniLaunching && javaVM == NULL)
{
if (vmSearchPath != NULL) vmName = vmSearchPath; /* used default VM searching */
errorMsg = malloc( (_tcslen(noVMMsg) + _tcslen(officialName) + _tcslen(vmName) + 10) * sizeof(_TCHAR) );
@@ -407,102 +424,162 @@ JNIEXPORT int run(int argc, _TCHAR* argv[], _TCHAR* vmArgs[])
}
#ifdef _WIN32
- if(debug || needConsole) {
+ if( jniLaunching && (debug || needConsole) ) {
createConsole();
}
#endif
- /* If the showsplash option was given */
- if (!noSplash && showSplashArg)
+ /* If the showsplash option was given and we are using JNI */
+ if (!noSplash && showSplashArg && jniLaunching)
{
showSplash(showSplashArg);
}
+ /* not using JNI launching, need some shared data */
+ if (!jniLaunching && createSharedData( &sharedID, MAX_SHARED_LENGTH )) {
+ if (debug) {
+ if (debug) displayMessage( officialName, shareMsg );
+ }
+ }
+
/* the startup jarFile goes on the classpath */
- cp = malloc((_tcslen(CLASSPATH_PREFIX) + _tcslen(jarFile) + 1) * sizeof(_TCHAR));
- cp = _tcscpy(cp, CLASSPATH_PREFIX);
- _tcscat(cp, jarFile);
+ if(jniLaunching) {
+ /* JNI launching, classpath is set using -Djava.class.path */
+ cp = malloc((_tcslen(CLASSPATH_PREFIX) + _tcslen(jarFile) + 1) * sizeof(_TCHAR));
+ cp = _tcscpy(cp, CLASSPATH_PREFIX);
+ _tcscat(cp, jarFile);
+ } else {
+ /* exec java, jar is specified with -jar */
+ cp = JAR;
+ cpValue = malloc((_tcslen(jarFile) + 1) * sizeof(_TCHAR));
+ _tcscpy(cpValue, jarFile);
+ }
/* Get the command to start the Java VM. */
userVMarg = vmArgs;
getVMCommand( argc, argv, &vmCommandArgs, &progCommandArgs );
+ if (!jniLaunching) {
+ vmCommand = combineLists(vmCommandArgs, progCommandArgs);
+ }
+
/* While the Java VM should be restarted */
- vmCommand = vmCommandArgs;
- vmCommandMsg = formatVmCommandMsg( vmCommand );
- if (debug) _tprintf( goVMMsg, vmCommandMsg );
- exitCode = startJavaVM(javaVM, vmCommandArgs, progCommandArgs );
- switch( exitCode ) {
- case 0: /* normal exit */
- break;
- case RESTART_LAST_EC:
- /* copy for relaunch, +1 to ensure NULL terminated */
- relaunchCommand = malloc((initialArgc + 1) * sizeof(_TCHAR*));
- memcpy(relaunchCommand, initialArgv, (initialArgc + 1) * sizeof(_TCHAR*));
- relaunchCommand[initialArgc] = 0;
- break;
- case RESTART_NEW_EC:
- if (exitData != 0) {
- if (vmCommandList != NULL) freeArgList( vmCommandList );
- vmCommandList = parseArgList( exitData );
- relaunchCommand = getRelaunchCommand(vmCommandList);
- } else {
- if (debug) displayMessage( officialName, shareMsg );
- }
- break;
- default: {
- _TCHAR *title = _tcsdup(officialName);
- vmCommand = NULL;
- errorMsg = NULL;
- if (exitData != 0) {
- errorMsg = exitData;
- if (_tcslen( errorMsg ) == 0) {
- free( errorMsg );
- errorMsg = NULL;
- } else {
- _TCHAR *str;
- if (_tcsncmp(errorMsg, _T_ECLIPSE("<title>"), _tcslen(_T_ECLIPSE("<title>"))) == 0) {
- str = _tcsstr(errorMsg, _T_ECLIPSE("</title>"));
- if (str != NULL) {
- free( title );
- str[0] = _T_ECLIPSE('\0');
- title = _tcsdup( errorMsg + _tcslen(_T_ECLIPSE("<title>")) );
- str = _tcsdup( str + _tcslen(_T_ECLIPSE("</title>")) );
- free( errorMsg );
- errorMsg = str;
- }
- }
- }
- } else {
- if (debug) displayMessage( title, shareMsg );
- }
- if (errorMsg == NULL) {
- errorMsg = malloc( (_tcslen(exitMsg) + _tcslen(vmCommandMsg) + 10) * sizeof(_TCHAR) );
- _stprintf( errorMsg, exitMsg, exitCode, vmCommandMsg );
- }
- displayMessage( title, errorMsg );
- free( title );
- free( errorMsg );
- break;
- }
+ while(running)
+ {
+ vmCommandMsg = formatVmCommandMsg( vmCommand, vmCommandArgs, progCommandArgs );
+ if (debug) _tprintf( goVMMsg, vmCommandMsg );
+
+ if(jniLaunching) {
+ exitCode = startJavaVM(vmLibrary, vmCommandArgs, progCommandArgs);
+ } else {
+ exitCode = launchJavaVM(javaVM, vmCommand);
+ }
+
+ switch( exitCode ) {
+ case 0: /* normal exit */
+ running = 0;
+ break;
+ case RESTART_LAST_EC:
+ if (jniLaunching) {
+ /* copy for relaunch, +1 to ensure NULL terminated */
+ relaunchCommand = malloc((initialArgc + 1) * sizeof(_TCHAR*));
+ memcpy(relaunchCommand, initialArgv, (initialArgc + 1) * sizeof(_TCHAR*));
+ relaunchCommand[initialArgc] = 0;
+ running = 0;
+ }
+ break;
+
+ case RESTART_NEW_EC:
+ if(!jniLaunching) {
+ getSharedData( sharedID, &exitData );
+ }
+ if (exitData != 0) {
+ if (vmCommandList != NULL) freeArgList( vmCommandList );
+ else free( vmCommand );
+ vmCommandList = parseArgList( exitData );
+ vmCommand = &vmCommandList[1]; /* command list starts with program */
+ if (jniLaunching) {
+ relaunchCommand = getRelaunchCommand(vmCommand);
+ running = 0;
+ }
+ } else {
+ if (debug) displayMessage( officialName, shareMsg );
+ }
+ break;
+ default: {
+ _TCHAR *title = _tcsdup(officialName);
+ running = 0;
+ errorMsg = NULL;
+ if(!jniLaunching) {
+ getSharedData( sharedID, &exitData );
+ }
+ if (exitData != 0) {
+ errorMsg = exitData;
+ if (_tcslen( errorMsg ) == 0) {
+ free( errorMsg );
+ errorMsg = NULL;
+ } else {
+ _TCHAR *str;
+ if (_tcsncmp(errorMsg, _T_ECLIPSE("<title>"), _tcslen(_T_ECLIPSE("<title>"))) == 0) {
+ str = _tcsstr(errorMsg, _T_ECLIPSE("</title>"));
+ if (str != NULL) {
+ free( title );
+ str[0] = _T_ECLIPSE('\0');
+ title = _tcsdup( errorMsg + _tcslen(_T_ECLIPSE("<title>")) );
+ str = _tcsdup( str + _tcslen(_T_ECLIPSE("</title>")) );
+ free( errorMsg );
+ errorMsg = str;
+ }
+ }
+ }
+ } else {
+ if (debug) displayMessage( title, shareMsg );
+ }
+ if (errorMsg == NULL) {
+ errorMsg = malloc( (_tcslen(exitMsg) + _tcslen(vmCommandMsg) + 10) * sizeof(_TCHAR) );
+ _stprintf( errorMsg, exitMsg, exitCode, vmCommandMsg );
+ }
+ displayMessage( title, errorMsg );
+ free( title );
+ free( errorMsg );
+ break;
+ }
+ }
+ free( vmCommandMsg );
}
if(relaunchCommand != NULL)
restartLauncher(program, relaunchCommand);
/* Cleanup time. */
- free( vmCommandMsg );
+ free( vmCommandArgs );
+ free( progCommandArgs );
free( jarFile );
- free( cp );
free( programDir );
free( program );
- if ( vmSearchPath != NULL ) free( vmSearchPath );
- if ( vmCommandList != NULL ) freeArgList( vmCommandList );
free( officialName );
+ if ( cp != JAR ) free( cp );
+ if ( cpValue != NULL) free( cpValue );
+ if ( vmSearchPath != NULL ) free( vmSearchPath );
+ if ( vmCommandList != NULL ) freeArgList( vmCommandList );
+ else if( exitData != NULL ) free( exitData );
return 0;
}
+static _TCHAR** combineLists( _TCHAR** c1, _TCHAR** c2 ) {
+ int n1 = -1, n2 = -1;
+ _TCHAR** result;
+
+ while(c1[++n1] != NULL) {}
+ while(c2[++n2] != NULL) {}
+
+ result = malloc((n1 + n2 + 1) * sizeof(_TCHAR*));
+ memset(result, 0, (n1 + n2 + 1) * sizeof(_TCHAR*));
+ memcpy(result, c1, n1 * sizeof(_TCHAR*));
+ memcpy(result + n1, c2, n2 * sizeof(_TCHAR*));
+ return result;
+}
/*
* Parse arguments of the command.
*/
@@ -642,16 +719,18 @@ static void getVMCommand( int argc, _TCHAR* argv[], _TCHAR **vmArgv[], _TCHAR **
/* For each required VM arg */
for (src = 0; src < nReqVMarg; src++)
- (*vmArgv)[ dst++ ] = *(reqVMarg[ src ]);
+ if( *(reqVMarg[src]) != NULL)
+ (*vmArgv)[ dst++ ] = *(reqVMarg[ src ]);
(*vmArgv)[dst] = NULL;
/* Program arguments */
/* OS <os> + WS <ws> + ARCH <arch> + LAUNCHER <launcher> + NAME <officialName> +
- * + LIBRARY <library> + SHOWSPLASH <cmd> + argv[] + VM + <vm> + VMARGS + vmArg + requiredVMargs
+ * + LIBRARY <library> + SHOWSPLASH <cmd> + EXITDATA <cmd> + STARTUP <jar> + argv[] + VM + <vm> +
+ * VMARGS + vmArg + requiredVMargs
* + NULL)
*/
- totalProgArgs = 2 + 2 + 2 + 2 + 2 + 2 + 2 + argc + 2 + 1 + nVMarg + nReqVMarg + 1;
+ totalProgArgs = 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + argc + 2 + 1 + nVMarg + nReqVMarg + 1;
*progArgv = malloc( totalProgArgs * sizeof( _TCHAR* ) );
dst = 0;
@@ -679,11 +758,21 @@ static void getVMCommand( int argc, _TCHAR* argv[], _TCHAR **vmArgv[], _TCHAR **
(*progArgv)[ dst++ ] = library;
}
+ /* the startup jar */
+ (*progArgv)[ dst++ ] = STARTUP;
+ (*progArgv)[ dst++ ] = jarFile;
+
/* Append the show splash window command, if defined. */
if (!noSplash)
{
(*progArgv)[ dst++ ] = SHOWSPLASH;
}
+
+ /* Append the exit data command. */
+ if (sharedID) {
+ (*progArgv)[ dst++ ] = EXITDATA;
+ (*progArgv)[ dst++ ] = sharedID;
+ }
/* Append the remaining user defined arguments. */
for (src = 1; src < argc; src++)
@@ -693,7 +782,10 @@ static void getVMCommand( int argc, _TCHAR* argv[], _TCHAR **vmArgv[], _TCHAR **
/* Append VM and VMARGS to be able to relaunch using exit data. */
(*progArgv)[ dst++ ] = VM;
- (*progArgv)[ dst++ ] = javaVM;
+ if(vmLibrary != NULL)
+ (*progArgv)[ dst++ ] = vmLibrary;
+ else
+ (*progArgv)[ dst++ ] = javaVM;
(*progArgv)[ dst++ ] = VMARGS;
for (src = 0; src < nVMarg; src++)
@@ -701,7 +793,8 @@ static void getVMCommand( int argc, _TCHAR* argv[], _TCHAR **vmArgv[], _TCHAR **
/* For each required VM arg */
for (src = 0; src < nReqVMarg; src++)
- (*progArgv)[ dst++ ] = *(reqVMarg[ src ]);
+ if (*(reqVMarg[src]) != NULL)
+ (*progArgv)[ dst++ ] = *(reqVMarg[ src ]);
(*progArgv)[ dst++ ] = NULL;
@@ -712,19 +805,28 @@ static void getVMCommand( int argc, _TCHAR* argv[], _TCHAR **vmArgv[], _TCHAR **
* This method formats a string with the JVM start command (and all arguments)
* that can be used in displaying error messages. The string returned from this
* method is probably not NLS compliant and must be deallocated by the caller.
+ *
+ * The arguments in the message are either args (if not null) or the combination
+ * of vmArgs + progArgs
*/
-static _TCHAR* formatVmCommandMsg( _TCHAR* args[] )
+static _TCHAR* formatVmCommandMsg( _TCHAR* args[], _TCHAR* vmArgs[], _TCHAR* progArgs[] )
{
int index;
- int length;
+ int length = 0;
+ _TCHAR** list;
_TCHAR* ch;
_TCHAR* message;
/* Determine the length of the message buffer. */
- length = 0;
- for (index = 0; args[index] != NULL; index++)
- {
- length += _tcslen(args[index]) + 1;
+ if(args != NULL) list = args;
+ else list = vmArgs;
+ while(list != NULL) {
+ for (index = 0; list[index] != NULL; index++)
+ {
+ length += _tcslen(list[index]) + 1;
+ }
+ if(list == vmArgs) list = progArgs;
+ else list = NULL;
}
message = malloc( (length + 5) * sizeof(_TCHAR) );
@@ -732,13 +834,19 @@ static _TCHAR* formatVmCommandMsg( _TCHAR* args[] )
on a new line. Otherwise, the Motif MessageBox does not automatically wrap
the messages and the message window can extend beyond both sides of the display. */
ch = message;
- for (index = 0; args[index] != NULL; index++)
- {
- if (args[index][0] == _T_ECLIPSE('-') && *(ch-1) == _T_ECLIPSE(' '))
- *(ch-1) = _T_ECLIPSE('\n');
- _tcscpy( ch, args[index] );
- ch += _tcslen( args[index] );
- *ch++ = _T_ECLIPSE(' ');
+ if(args != NULL) list = args;
+ else list = vmArgs;
+ while(list != NULL) {
+ for (index = 0; list[index] != NULL; index++)
+ {
+ if (list[index][0] == _T_ECLIPSE('-') && *(ch-1) == _T_ECLIPSE(' '))
+ *(ch-1) = _T_ECLIPSE('\n');
+ _tcscpy( ch, list[index] );
+ ch += _tcslen( list[index] );
+ *ch++ = _T_ECLIPSE(' ');
+ }
+ if(list == vmArgs) list = progArgs;
+ else list = NULL;
}
*ch = _T_ECLIPSE('\0');
@@ -883,7 +991,7 @@ static _TCHAR ** getRelaunchCommand( _TCHAR **vmCommand )
if (vmCommand == NULL) return NULL;
while(vmCommand[++i] != NULL){
if ( begin == -1 && _tcsicmp( vmCommand[i], *reqVMarg[req] ) == 0) {
- if(reqVMarg[++req] == NULL){
+ if(reqVMarg[++req] == NULL || *reqVMarg[req] == NULL){
begin = i + 1;
}
}
@@ -901,9 +1009,8 @@ static _TCHAR ** getRelaunchCommand( _TCHAR **vmCommand )
i++;
continue;
}
- } else if(_tcsicmp(vmCommand[i], JAR) == 0 ) {
- /* skip -jar */
- i++;
+ } else if(_tcsncmp(vmCommand[i], CLASSPATH_PREFIX, _tcslen(CLASSPATH_PREFIX)) == 0) {
+ /* skip -Djava.class.path=... */
continue;
}
relaunch[idx++] = vmCommand[i];
diff --git a/bundles/org.eclipse.equinox.executable/library/eclipseJNI.c b/bundles/org.eclipse.equinox.executable/library/eclipseJNI.c
index 69572a839..02db6247f 100644
--- a/bundles/org.eclipse.equinox.executable/library/eclipseJNI.c
+++ b/bundles/org.eclipse.equinox.executable/library/eclipseJNI.c
@@ -13,19 +13,20 @@
#include "eclipseJNI.h"
#include "eclipseCommon.h"
#include "eclipseOS.h"
+#include "eclipseShm.h"
#include <stdlib.h>
#include <string.h>
static JNINativeMethod natives[] = {{"_update_splash", "()V", &update_splash},
{"_get_splash_handle", "()J", &get_splash_handle},
- {"_set_exit_data", "(Ljava/lang/String;)V", &set_exit_data},
+ {"_set_exit_data", "(Ljava/lang/String;Ljava/lang/String;)V", &set_exit_data},
{"_show_splash", "(Ljava/lang/String;)V", &show_splash},
{"_takedown_splash", "()V", &takedown_splash}};
/* local methods */
static jstring newJavaString(JNIEnv *env, _TCHAR * str);
-static void setExitData(JNIEnv *env, jstring s);
+static void setExitData(JNIEnv *env, jstring id, jstring s);
static void splash(JNIEnv *env, jstring s);
static void registerNatives(JNIEnv *env);
@@ -36,13 +37,13 @@ static void registerNatives(JNIEnv *env);
* registerNatives gets called.
*/
#ifndef UNICODE
-void (* exitDataHook)(JNIEnv *env, jstring s);
+void (* exitDataHook)(JNIEnv *env, jstring id, jstring s);
void (* dispatchHook)();
long (* splashHandleHook)();
void (* showSplashHook)(JNIEnv *env, jstring s);
void (* takeDownHook)();
#else
-extern void (* exitDataHook)(JNIEnv *env, jstring s);
+extern void (* exitDataHook)(JNIEnv *env, jstring id, jstring s);
extern void (* dispatchHook)();
extern long (* splashHandleHook)();
extern void (* showSplashHook)(JNIEnv *env, jstring s);
@@ -51,11 +52,11 @@ extern void (* takeDownHook)();
#ifndef UNICODE
/* JNI Callback methods */
-JNIEXPORT void JNICALL set_exit_data(JNIEnv * env, jobject obj, jstring s){
+JNIEXPORT void JNICALL set_exit_data(JNIEnv * env, jobject obj, jstring id, jstring s){
if(exitDataHook != NULL)
- exitDataHook(env, s);
+ exitDataHook(env, id, s);
else /* hook was not set, just call the ANSI version */
- setExitData(env, s);
+ setExitData(env, id, s);
}
JNIEXPORT void JNICALL update_splash(JNIEnv * env, jobject obj){
@@ -91,12 +92,11 @@ static void registerNatives(JNIEnv *env) {
jclass bridge = (*env)->FindClass(env, "org/eclipse/equinox/launcher/JNIBridge");
if(bridge != NULL) {
int numNatives = sizeof(natives) / sizeof(natives[0]);
- (*env)->RegisterNatives(env, bridge, natives, numNatives);
-
- if( (*env)->ExceptionOccurred(env) != 0 ){
- (*env)->ExceptionDescribe(env);
- (*env)->ExceptionClear(env);
- }
+ (*env)->RegisterNatives(env, bridge, natives, numNatives);
+ }
+ if( (*env)->ExceptionOccurred(env) != 0 ){
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
}
/*set hooks*/
splashHandleHook = &getSplashHandle;
@@ -107,43 +107,77 @@ static void registerNatives(JNIEnv *env) {
}
static void splash(JNIEnv *env, jstring s) {
- const _TCHAR* data;
- data = JNI_GetStringChars(env, s);
- showSplash(data);
- JNI_ReleaseStringChars(env, s, data);
+ const _TCHAR* data = NULL;
+ if(s != NULL) {
+ data = JNI_GetStringChars(env, s);
+ if(data != NULL) {
+ showSplash(data);
+ JNI_ReleaseStringChars(env, s, data);
+ } else {
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ }
+ }
}
-static void setExitData(JNIEnv *env, jstring s){
- const _TCHAR* data;
+static void setExitData(JNIEnv *env, jstring id, jstring s){
+ const _TCHAR* data = NULL;
+ const _TCHAR* sharedId = NULL;
int length;
- length = (*env)->GetStringLength(env, s);
- data = JNI_GetStringChars(env, s);
-
- exitData = malloc((length + 1) * sizeof(_TCHAR*));
- _tcsncpy( exitData, data, length);
- exitData[length] = 0;
- JNI_ReleaseStringChars(env, s, data);
+ if(s != NULL) {
+ length = (*env)->GetStringLength(env, s);
+ if(!(*env)->ExceptionOccurred(env)) {
+ data = JNI_GetStringChars(env, s);
+ if (data != NULL) {
+ if(id != NULL) {
+ sharedId = JNI_GetStringChars(env, id);
+ if(sharedId != NULL) {
+ setSharedData(sharedId, data);
+ JNI_ReleaseStringChars(env, id, sharedId);
+ }
+ } else {
+ exitData = malloc((length + 1) * sizeof(_TCHAR*));
+ _tcsncpy( exitData, data, length);
+ exitData[length] = 0;
+ }
+ JNI_ReleaseStringChars(env, s, data);
+ }
+ }
+ if(data == NULL && sharedId == NULL) {
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ }
+ }
}
static jstring newJavaString(JNIEnv *env, _TCHAR * str)
{
- jstring newString = 0;
+ jstring newString = NULL;
int length = _tcslen(str);
#ifdef UNICODE
newString = (*env)->NewString(env, str, length);
#else
jbyteArray bytes = (*env)->NewByteArray(env, length);
- (*env)->SetByteArrayRegion(env, bytes, 0, length, str);
- if (!(*env)->ExceptionOccurred(env)) {
- jclass stringClass = (*env)->FindClass(env, "java/lang/String");
- jmethodID ctor = (*env)->GetMethodID(env, stringClass, "<init>", "([B)V");
- newString = (*env)->NewObject(env, stringClass, ctor, bytes);
+ if(bytes != NULL) {
+ (*env)->SetByteArrayRegion(env, bytes, 0, length, str);
+ if (!(*env)->ExceptionOccurred(env)) {
+ jclass stringClass = (*env)->FindClass(env, "java/lang/String");
+ if(stringClass != NULL) {
+ jmethodID ctor = (*env)->GetMethodID(env, stringClass, "<init>", "([B)V");
+ if(ctor != NULL) {
+ newString = (*env)->NewObject(env, stringClass, ctor, bytes);
+ }
+ }
+ }
+ (*env)->DeleteLocalRef(env, bytes);
}
- (*env)->DeleteLocalRef(env, bytes);
#endif
-
+ if(newString == NULL) {
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ }
return newString;
}
@@ -157,11 +191,26 @@ static jobjectArray createRunArgs( JNIEnv *env, _TCHAR * args[] ) {
while(args[++length] != NULL);
stringClass = (*env)->FindClass(env, "java/lang/String");
- stringArray = (*env)->NewObjectArray(env, length, stringClass, 0);
- for( index = 0; index < length; index++) {
- string = newJavaString(env, args[index]);
- (*env)->SetObjectArrayElement(env, stringArray, index, string);
- (*env)->DeleteLocalRef(env, string);
+ if(stringClass != NULL) {
+ stringArray = (*env)->NewObjectArray(env, length, stringClass, 0);
+ if(stringArray != NULL) {
+ for( index = 0; index < length; index++) {
+ string = newJavaString(env, args[index]);
+ if(string != NULL) {
+ (*env)->SetObjectArrayElement(env, stringArray, index, string);
+ (*env)->DeleteLocalRef(env, string);
+ } else {
+ (*env)->DeleteLocalRef(env, stringArray);
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ return NULL;
+ }
+ }
+ }
+ }
+ if(stringArray == NULL) {
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
}
return stringArray;
}
@@ -170,7 +219,7 @@ int startJavaVM( _TCHAR* libPath, _TCHAR* vmArgs[], _TCHAR* progArgs[] )
{
int i;
int numVMArgs = -1;
- int jvmExitCode = 0;
+ int jvmExitCode = -1;
void * jniLibrary;
JNI_createJavaVM createJavaVM;
JavaVMInitArgs init_args;
@@ -224,21 +273,27 @@ int startJavaVM( _TCHAR* libPath, _TCHAR* vmArgs[], _TCHAR* progArgs[] )
mainClass = (*env)->FindClass(env, "org/eclipse/equinox/launcher/Main");
if(mainClass != NULL) {
mainConstructor = (*env)->GetMethodID(env, mainClass, "<init>", "()V");
- mainObject = (*env)->NewObject(env, mainClass, mainConstructor);
- runMethod = (*env)->GetMethodID(env, mainClass, "run", "([Ljava/lang/String;)I");
- if(runMethod != NULL) {
- methodArgs = createRunArgs(env, progArgs);
- jvmExitCode = (*env)->CallIntMethod(env, mainObject, runMethod, methodArgs);
- }
- } else {
- if((*env)->ExceptionOccurred(env)){
- (*env)->ExceptionDescribe(env);
- (*env)->ExceptionClear(env);
+ if(mainConstructor != NULL) {
+ mainObject = (*env)->NewObject(env, mainClass, mainConstructor);
+ if(mainObject != NULL) {
+ runMethod = (*env)->GetMethodID(env, mainClass, "run", "([Ljava/lang/String;)I");
+ if(runMethod != NULL) {
+ methodArgs = createRunArgs(env, progArgs);
+ if(methodArgs != NULL) {
+ jvmExitCode = (*env)->CallIntMethod(env, mainObject, runMethod, methodArgs);
+ (*env)->DeleteLocalRef(env, methodArgs);
+ }
+ }
+ (*env)->DeleteLocalRef(env, mainObject);
+ }
}
+ }
+ if((*env)->ExceptionOccurred(env)){
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
}
- /*(*jvm)->DestroyJavaVM(jvm);*/
+ (*jvm)->DestroyJavaVM(jvm);
}
- free(progArgs);
/* toNarrow allocated new strings, free them */
for(i = 0; i < numVMArgs; i++){
diff --git a/bundles/org.eclipse.equinox.executable/library/eclipseJNI.h b/bundles/org.eclipse.equinox.executable/library/eclipseJNI.h
index 579d4ee2b..8c4fe2c86 100644
--- a/bundles/org.eclipse.equinox.executable/library/eclipseJNI.h
+++ b/bundles/org.eclipse.equinox.executable/library/eclipseJNI.h
@@ -45,9 +45,9 @@ extern "C" {
#endif
/*
* org_eclipse_equinox_launcher_JNIBridge#_set_exit_data
- * Signature: (Ljava/lang/String;)V
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)V
*/
-JNIEXPORT void JNICALL set_exit_data(JNIEnv *, jobject, jstring);
+JNIEXPORT void JNICALL set_exit_data(JNIEnv *, jobject, jstring, jstring);
/*
* org_eclipse_equinox_launcher_JNIBridge#_update_splash
diff --git a/bundles/org.eclipse.equinox.executable/library/eclipseMain.c b/bundles/org.eclipse.equinox.executable/library/eclipseMain.c
index 15a644a68..53c43d885 100644
--- a/bundles/org.eclipse.equinox.executable/library/eclipseMain.c
+++ b/bundles/org.eclipse.equinox.executable/library/eclipseMain.c
@@ -334,7 +334,7 @@ static _TCHAR* findLibrary(_TCHAR* library, _TCHAR* program)
return findFile(library, _T_ECLIPSE("eclipse"));
} else {
/* file, return it */
- return library;
+ return _tcsdup(library);
}
}
diff --git a/bundles/org.eclipse.equinox.executable/library/eclipseOS.h b/bundles/org.eclipse.equinox.executable/library/eclipseOS.h
index e2e1cb5f1..91cb40a95 100644
--- a/bundles/org.eclipse.equinox.executable/library/eclipseOS.h
+++ b/bundles/org.eclipse.equinox.executable/library/eclipseOS.h
@@ -29,6 +29,7 @@
#define getSplashHandle getSplashHandleW
#define takeDownSplash takeDownSplashW
#define restartLauncher restartLauncherW
+#define launchJavaVM launchJavaVMW
#endif
/* Operating System Dependent Information */
@@ -106,5 +107,8 @@ extern void takeDownSplash();
extern void restartLauncher( _TCHAR* program, _TCHAR* args[] );
+/* launch the vm in a separate process and wait for it to finish */
+extern int launchJavaVM( _TCHAR* program, _TCHAR* args[] );
+
#endif /* ECLIPSE_OS_H */
diff --git a/bundles/org.eclipse.equinox.executable/library/eclipseShm.c b/bundles/org.eclipse.equinox.executable/library/eclipseShm.c
new file mode 100644
index 000000000..68f0c6f09
--- /dev/null
+++ b/bundles/org.eclipse.equinox.executable/library/eclipseShm.c
@@ -0,0 +1,257 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Silenio Quarti
+ *******************************************************************************/
+
+#include "eclipseOS.h"
+#include "eclipseShm.h"
+
+#ifdef _WIN32
+
+#include <stdio.h>
+
+#ifdef __MINGW32__
+#include <stdlib.h>
+#endif
+
+int createSharedData(_TCHAR** id, int size) {
+ HANDLE mapHandle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, size, NULL);
+ if (mapHandle == 0) return -1;
+ if (id != NULL) {
+ *id = malloc(18 * sizeof(_TCHAR));
+ _stprintf(*id, _T_ECLIPSE("%lx_%lx"), GetCurrentProcessId(), (DWORD) mapHandle);
+ }
+ return 0;
+}
+
+static int getShmID(const _TCHAR* id, LPDWORD processID, LPHANDLE handle) {
+ if (id != NULL && _tcslen(id) > 0) {
+ DWORD i1, i2;
+ if (_stscanf(id, _T_ECLIPSE("%lx_%lx"), &i1, &i2) != 2) return -1;
+ *processID = (DWORD)i1;
+ *handle = (HANDLE)i2;
+ return 0;
+ }
+ return -1;
+}
+
+int destroySharedData(_TCHAR* id) {
+ DWORD processID;
+ HANDLE handle;
+ if (getShmID(id, &processID, &handle) == -1) return -1;
+ if (!CloseHandle(handle)) return -1;
+ return 0;
+}
+
+int getSharedData(_TCHAR* id, _TCHAR** data) {
+ _TCHAR *sharedData, *newData = NULL;
+ DWORD processID;
+ HANDLE handle, mapHandle = NULL, processHandle;
+ if (getShmID(id, &processID, &handle) == -1) return -1;
+ if (processID == GetCurrentProcessId()) {
+ mapHandle = handle;
+ } else {
+ processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
+ if (processHandle == NULL) return -1;
+ DuplicateHandle(processHandle, handle, GetCurrentProcess(), &mapHandle, DUPLICATE_SAME_ACCESS, FALSE, DUPLICATE_SAME_ACCESS);
+ CloseHandle(processHandle);
+ }
+ if (mapHandle == NULL) return -1;
+ sharedData = MapViewOfFile(handle, FILE_MAP_WRITE, 0, 0, 0);
+ if (sharedData == NULL) return -1;
+ if (data != NULL) {
+ int length = (_tcslen(sharedData) + 1) * sizeof(_TCHAR);
+ newData = malloc(length);
+ memcpy(newData, sharedData, length);
+ }
+ if (!UnmapViewOfFile(sharedData)) {
+ free(newData);
+ return -1;
+ }
+ if (handle != mapHandle) {
+ CloseHandle(mapHandle);
+ }
+ *data = newData;
+ return 0;
+}
+
+int setSharedData(const _TCHAR* id, const _TCHAR* data) {
+ _TCHAR* sharedData;
+ DWORD processID;
+ HANDLE handle, mapHandle = NULL, processHandle;
+ if (getShmID(id, &processID, &handle) == -1) return -1;
+ if (processID == GetCurrentProcessId()) {
+ mapHandle = handle;
+ } else {
+ processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
+ if (processHandle == NULL) return -1;
+ DuplicateHandle(processHandle, handle, GetCurrentProcess(), &mapHandle, DUPLICATE_SAME_ACCESS, FALSE, DUPLICATE_SAME_ACCESS);
+ CloseHandle(processHandle);
+ }
+ if (mapHandle == NULL) return -1;
+ sharedData = MapViewOfFile(mapHandle, FILE_MAP_WRITE, 0, 0, 0);
+ if (sharedData == NULL) return -1;
+ if (data != NULL) {
+ int length = (_tcslen(data) + 1) * sizeof(_TCHAR);
+ memcpy(sharedData, data, length);
+ } else {
+ memset(sharedData, 0, sizeof(_TCHAR));
+ }
+ if (!UnmapViewOfFile(sharedData)) {
+ return -1;
+ }
+ if (handle != mapHandle) {
+ CloseHandle(mapHandle);
+ }
+ return 0;
+}
+
+#elif PHOTON
+
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int createSharedData(char** id, int size) {
+ int fd;
+ char* location = "/tmp/eclipse_%x";
+ char* name = malloc(strlen(location) + 9);
+ sprintf(name, location, getpid());
+ if ((fd = shm_open(name, O_RDWR | O_CREAT, 0666 )) == -1) return -1;
+ if (ftruncate(fd, size) == -1 ) {
+ shm_unlink(name);
+ return -1;
+ }
+ close( fd );
+ if (id != NULL) {
+ *id = name;
+ }
+ return 0;
+}
+
+int destroySharedData(char* id) {
+ return shm_unlink(id);
+}
+
+int getSharedData(char* id, char** data) {
+ int fd, length, size;
+ char *sharedData, *newData = NULL;
+ if ((fd = shm_open(id, O_RDWR, 0666 )) == -1) return -1;
+ size = lseek(fd, 0, SEEK_END);
+ sharedData = mmap( 0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
+ if (sharedData != MAP_FAILED) {
+ if (data != NULL) {
+ length = strlen(sharedData) + 1;
+ newData = malloc(length);
+ memcpy(newData, sharedData, length);
+ }
+ munmap(sharedData, size);
+ }
+ close(fd);
+ *data = newData;
+ return newData == NULL ? -1 : 0;
+}
+
+int setSharedData(char* id, char* data) {
+ int fd, length, size;
+ char *sharedData;
+ if ((fd = shm_open(id, O_RDWR, 0666 )) == -1) return -1;
+ size = lseek(fd, 0, SEEK_END);
+ sharedData = mmap( 0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
+ if (sharedData != MAP_FAILED) {
+ if (data != NULL) {
+ length = strlen(data) + 1;
+ memcpy(sharedData, data, length);
+ } else {
+ memset(sharedData, 0, sizeof(char));
+ }
+ munmap(sharedData, size);
+ }
+ close(fd);
+ return 0;
+}
+
+#else /* Unix like platforms */
+
+#include <sys/shm.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+int createSharedData(char** id, int size) {
+ int shmid;
+ key_t key = getpid();
+ if ((shmid = shmget(key, size, IPC_CREAT | 0666)) < 0) {
+ return -1;
+ }
+ if (id != NULL) {
+ *id = malloc(9 * sizeof(char));
+ sprintf(*id, "%x", shmid);
+ }
+ return 0;
+}
+
+static int getShmID(const char* id) {
+ int shmid = -1;
+ /* Determine the shared memory id. */
+ if (id != NULL && strlen(id) > 0) {
+ sscanf(id, "%x", &shmid);
+ }
+ return shmid;
+}
+
+int destroySharedData(char* id) {
+ int shmid = getShmID(id);
+ if (shmid == -1) return -1;
+ return shmctl(shmid, IPC_RMID, NULL);
+}
+
+int getSharedData( char* id, char** data ) {
+ char *sharedData, *newData = NULL;
+ int length;
+ int shmid = getShmID(id);
+ if (shmid == -1) return -1;
+ sharedData = shmat(shmid, (void *)0, 0);
+ if (sharedData == (char *)(-1)) return -1;
+ length = strlen(sharedData) + 1;
+ newData = malloc(length);
+ memcpy(newData, sharedData, length);
+ if (shmdt(sharedData) != 0) {
+ free(newData);
+ return -1;
+ }
+ *data = newData;
+ return 0;
+}
+
+int setSharedData(const char* id, const char* data) {
+ char* sharedData;
+ int length;
+ int shmid = getShmID(id);
+ if (shmid == -1) return -1;
+ sharedData = shmat(shmid, (void *)0, 0);
+ if (sharedData == (char *)(-1)) return -1;
+ if (data != NULL) {
+ length = strlen(data) + 1;
+ memcpy(sharedData, data, length);
+ } else {
+ memset(sharedData, 0, sizeof(char));
+ }
+ if (shmdt(sharedData) != 0) {
+ return -1;
+ }
+ return 0;
+}
+
+#endif /* Unix like platforms */
diff --git a/bundles/org.eclipse.equinox.executable/library/eclipseShm.h b/bundles/org.eclipse.equinox.executable/library/eclipseShm.h
new file mode 100644
index 000000000..be3b5d3ac
--- /dev/null
+++ b/bundles/org.eclipse.equinox.executable/library/eclipseShm.h
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Silenio Quarti
+ *******************************************************************************/
+
+#ifndef ECLIPSE_SHM_H
+#define ECLIPSE_SHM_H
+
+#ifdef UNICODE
+#define createSharedData createSharedDataW
+#define destroySharedData destroySharedDataW
+#define getSharedData getSharedDataW
+#define setSharedData setSharedDataW
+#endif
+
+/* Shared memory utilities */
+
+/**
+ * Creates and initializes a shared memory segment
+ * with the specified size in bytes. The id for the
+ * shared memory segment is stored in the id argument
+ * and can be used from any process. It must be freed
+ * with free().
+ *
+ * Returns 0 if success.
+ */
+extern int createSharedData(_TCHAR** id, int size);
+
+/**
+ * Destroy the shared memory segment specified by the
+ * id argument. The id is the same as the one return
+ * by createSharedData(). This function must be called
+ * by the same process that created the segment.
+ *
+ * Returns 0 if success.
+ */
+extern int destroySharedData(_TCHAR* id);
+
+/**
+ * Gets a copy of the shared memory segment specified
+ * by the id argument. The copy is stored in the data
+ * argument as a null terminated string and must be
+ * freed by free().
+ *
+ * Returns 0 if success.
+ */
+extern int getSharedData(_TCHAR* id, _TCHAR** data);
+
+/**
+ * Sets the shared memory segment specified by the id
+ * argument with a null terminated string specified by
+ * data.
+ *
+ * Returns 0 if sucess.
+ */
+extern int setSharedData(const _TCHAR* id, const _TCHAR* data);
+
+#endif /* ECLIPSE_SHM_H */
+
+
diff --git a/bundles/org.eclipse.equinox.executable/library/win32/eclipseWin.c b/bundles/org.eclipse.equinox.executable/library/win32/eclipseWin.c
index 4446f6057..5234bb5e1 100644
--- a/bundles/org.eclipse.equinox.executable/library/win32/eclipseWin.c
+++ b/bundles/org.eclipse.equinox.executable/library/win32/eclipseWin.c
@@ -36,6 +36,14 @@ _TCHAR* shippedVMDir = _T("jre\\bin\\");
/* Define the window system arguments for the Java VM. */
static _TCHAR* argVM[] = { NULL };
+/* Define local variables for running the JVM and detecting its exit. */
+static int jvmProcess = 0;
+static int jvmExitCode = 0;
+static int jvmExitTimeout = 100;
+static int jvmExitTimerId = 99;
+
+static void CALLBACK detectJvmExit( HWND hwnd, UINT uMsg, UINT id, DWORD dwTime );
+
/* define default locations in which to find the jvm shared library
* these are paths relative to the java exe, the shared library is
* for example jvmLocations[0] + dirSeparator + vmLibrary */
@@ -215,7 +223,7 @@ _TCHAR* findVMLibrary( _TCHAR* command ) {
return NULL;
}
-void restartLauncher( _TCHAR* program, _TCHAR* args[] )
+static _TCHAR* buildCommandLine( _TCHAR* program, _TCHAR* args[] )
{
int index, length;
_TCHAR *commandLine, *ch, *space;
@@ -246,6 +254,11 @@ void restartLauncher( _TCHAR* program, _TCHAR* args[] )
*ch++ = _T(' ');
}
*ch = _T('\0');
+ return commandLine;
+}
+void restartLauncher( _TCHAR* program, _TCHAR* args[] )
+{
+ _TCHAR* commandLine = buildCommandLine(program, args);
{
STARTUPINFO si;
@@ -257,3 +270,76 @@ void restartLauncher( _TCHAR* program, _TCHAR* args[] )
}
free(commandLine);
}
+
+int launchJavaVM( _TCHAR* program, _TCHAR* args[] )
+{
+ MSG msg;
+ _TCHAR* commandLine;
+
+ commandLine = buildCommandLine(program, args);
+
+ /*
+ * Start the Java virtual machine. Use CreateProcess() instead of spawnv()
+ * otherwise the arguments cannot be freed since spawnv() segments fault.
+ */
+ {
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ GetStartupInfo(&si);
+ if (CreateProcess(NULL, commandLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
+ CloseHandle( pi.hThread );
+ jvmProcess = (int)pi.hProcess;
+ }
+ }
+
+ free( commandLine );
+ free( args );
+
+ /* If the child process (JVM) would not start */
+ if (jvmProcess == -1)
+ {
+ /* Return the error number. */
+ jvmExitCode = errno;
+ jvmProcess = 0;
+ }
+
+ /* else */
+ else
+ {
+ /* Set a timer to detect JVM process termination. */
+ SetTimer( topWindow, jvmExitTimerId, jvmExitTimeout, detectJvmExit );
+
+ /* Process messages until the JVM terminates.
+ This launcher process must continue to process events until the JVM exits
+ or else Windows 2K will hang if the desktop properties (e.g., background) are
+ changed by the user. Windows does a SendMessage() to every top level window
+ process, which blocks the caller until the process responds. */
+ while (jvmProcess != 0)
+ {
+ GetMessage( &msg, NULL, 0, 0 );
+ TranslateMessage( &msg );
+ DispatchMessage( &msg );
+ }
+
+ /* Kill the timer. */
+ KillTimer( topWindow, jvmExitTimerId );
+ }
+
+ /* Return the exit code from the JVM. */
+ return jvmExitCode;
+}
+
+/* Detect JVM Process Termination */
+static void CALLBACK detectJvmExit( HWND hwnd, UINT uMsg, UINT id, DWORD dwTime )
+{
+ DWORD exitCode;
+
+ /* If the JVM process has terminated */
+ if (!GetExitCodeProcess( (HANDLE)jvmProcess, &exitCode ) ||
+ exitCode != STILL_ACTIVE)
+ {
+ /* Save the JVM exit code. This should cause the loop in startJavaVM() to exit. */
+ jvmExitCode = exitCode;
+ jvmProcess = 0;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.executable/library/win32/make_mingw.mak b/bundles/org.eclipse.equinox.executable/library/win32/make_mingw.mak
index a68f52193..251c71849 100644
--- a/bundles/org.eclipse.equinox.executable/library/win32/make_mingw.mak
+++ b/bundles/org.eclipse.equinox.executable/library/win32/make_mingw.mak
@@ -51,8 +51,8 @@ endif
MAIN_OBJS = eclipseMain.o aeclipseMain.o
COMMON_OBJS = eclipseConfig.o eclipseCommon.o eclipseWinCommon.o\
aeclipseConfig.o aeclipseCommon.o aeclipseWinCommon.o
-DLL_OBJS = eclipse.o eclipseWin.o eclipseUtil.o eclipseJNI.o\
- aeclipse.o aeclipseWin.o aeclipseUtil.o aeclipseJNI.o
+DLL_OBJS = eclipse.o eclipseWin.o eclipseUtil.o eclipseJNI.o eclipseShm.o\
+ aeclipse.o aeclipseWin.o aeclipseUtil.o aeclipseJNI.o aeclipseShm.o
LIBS = -lkernel32 -luser32 -lgdi32 -lcomctl32 -lmsvcrt
LDFLAGS = -mwindows -mno-cygwin
@@ -107,6 +107,12 @@ eclipseWin.o: ../eclipseOS.h ../eclipseUnicode.h eclipseWin.c
eclipseJNI.o: ../eclipseUnicode.h ../eclipseJNI.c
$(CC) $(DEBUG) $(WCFLAGS) -c -o $@ ../eclipseJNI.c
+eclipseShm.o: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c
+ $(CC) $(DEBUG) $(WCFLAGS) -c -o $@ ../eclipseShm.c
+
+aeclipseShm.o: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c
+ $(CC) $(DEBUG) $(ACFLAGS) -c -o $@ ../eclipseShm.c
+
aeclipse.o: ../eclipseOS.h ../eclipseUnicode.h ../eclipseCommon.h ../eclipse.c
$(CC) $(DEBUG) $(ACFLAGS) -c -o $@ ../eclipse.c
diff --git a/bundles/org.eclipse.equinox.executable/library/win32/make_win32.mak b/bundles/org.eclipse.equinox.executable/library/win32/make_win32.mak
index c79829caf..4648b4370 100644
--- a/bundles/org.eclipse.equinox.executable/library/win32/make_win32.mak
+++ b/bundles/org.eclipse.equinox.executable/library/win32/make_win32.mak
@@ -30,8 +30,8 @@ PROGRAM_LIBRARY = eclipse_$(LIB_VERSION).dll
MAIN_OBJS = eclipseMain.obj aeclipseMain.obj
COMMON_OBJS = eclipseConfig.obj eclipseCommon.obj eclipseWinCommon.obj\
aeclipseConfig.obj aeclipseCommon.obj aeclipseWinCommon.obj
-DLL_OBJS = eclipse.obj eclipseWin.obj eclipseUtil.obj eclipseJNI.obj\
- aeclipse.obj aeclipseWin.obj aeclipseUtil.obj aeclipseJNI.obj
+DLL_OBJS = eclipse.obj eclipseWin.obj eclipseUtil.obj eclipseJNI.obj eclipseShm.obj\
+ aeclipse.obj aeclipseWin.obj aeclipseUtil.obj aeclipseJNI.obj aeclipseShm.obj
LIBS = kernel32.lib user32.lib comctl32.lib msvcrt.lib
DLL_LIBS = kernel32.lib user32.lib comctl32.lib gdi32.lib Advapi32.lib msvcrt.lib
@@ -73,6 +73,12 @@ eclipseWinCommon.obj: ../eclipseCommon.h eclipseWinCommon.c
eclipseJNI.obj: ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.c
$(CC) $(DEBUG) $(wcflags) $(cvarsdll) /Fo$*.obj ../eclipseJNI.c
+eclipseShm.obj: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c
+ $(CC) $(DEBUG) $(wcflags) $(cvarsdll) /Fo$*.obj ../eclipseShm.c
+
+aeclipseShm.obj: ../eclipseShm.h ../eclipseUnicode.h ../eclipseShm.c
+ $(CC) $(DEBUG) $(acflags) $(cvarsdll) /Fo$*.obj ../eclipseShm.c
+
aeclipseJNI.obj: ../eclipseCommon.h ../eclipseOS.h ../eclipseJNI.c
$(cc) $(DEBUG) $(acflags) $(cvarsdll) /FoaeclipseJNI.obj ../eclipseJNI.c

Back to the top