diff options
author | Andrew Niefer | 2007-01-16 22:22:51 +0000 |
---|---|---|
committer | Andrew Niefer | 2007-01-16 22:22:51 +0000 |
commit | de9a521a158b9c93f48c593fc7c55739247a9c13 (patch) | |
tree | a9d9493c180ad7f6c12d9a301450acb0352c6c92 | |
parent | ae98f7e7567709aff2e04f0fb01440dfabbac5ec (diff) | |
download | rt.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
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 |