blob: 5148642981f0672af2413482cafdb0a3e32e263d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define USING_VMI /* Used in header files */
#include "jni.h" /* for definitions of JavaVM */
#include "hycomp.h" /* for portable types (UDATA,etc...) */
#include "hythread.h" /* for synchronization */
#include "hyport.h" /* for port library */
#include "hyexelibnls.h" /* nls strings */
#include "libhlp.h" /* defaults and environment variables and string buffer functions */
#include "strhelp.h" /* for properties file parsing */
#ifdef HY_NO_THR
#include "main_hlp.h" /* plaftorm specific launcher helpers */
#endif /* HY_NO_THR */
#include <string.h>
#include <stdlib.h>
#ifdef ZOS
#include <unistd.h>
#endif
#define PORT_LIB_OPTION "_org.apache.harmony.vmi.portlib"
#define HY_COPYRIGHT_STRING "Apache Harmony Launcher : (c) Copyright 1991, 2009 The Apache Software Foundation or its licensors, as applicable."
/* Tools launchers will invoke HY_TOOLS_PACKAGE+"."+<execname>+"."+HY_TOOLS_MAIN_TYPE */
#define HY_TOOLS_PACKAGE "org.apache.harmony.tools"
#define HY_TOOLS_MAIN_TYPE "Main"
#define HY_TOOLS_PATH "tools.jar"
#define HY_TOOLS_PROP "-Dorg.apache.harmony.tool=true"
#define HARMONY_JARRUNNER_CLASSNAME "org.apache.harmony.vm.JarRunner"
#if defined(WIN32)
#define PLATFORM_STRNICMP _strnicmp
#endif
#if defined(LINUX) || defined(FREEBSD) || defined(AIX) || defined(MACOSX) || defined(ZOS)
#define PLATFORM_STRNICMP strncasecmp
#endif
static int invocation
PROTOTYPE ((HyPortLibrary * portLibrary, int argc, char **argv, UDATA handle,
jint version, jboolean ignoreUnrecognized, char *mainClass,
UDATA classArg, char *propertiesFileName,
int isStandaloneJar, char *vmdllsubdir, int versionFlag));
static int createVMArgs
PROTOTYPE ((HyPortLibrary * portLibrary, int argc, char **argv,
jint version, jboolean ignoreUnrecognized,
JavaVMInitArgs * vm_args,
UDATA classArg, char *propertiesFileName,
int isStandaloneJar, char **mainClassJar, char *vmdllsubdir));
char *VMCALL vmdll_parseCmdLine
PROTOTYPE ((HyPortLibrary * portLibrary, UDATA lastLegalArg, char **argv));
char *VMCALL vmdlldir_parseCmdLine
#ifndef HY_NO_THR
PROTOTYPE ((HyPortLibrary * portLibrary, UDATA lastLegalArg, char **argv));
#else /* HY_NO_THR */
PROTOTYPE ((UDATA lastLegalArg, char **argv));
#endif /* HY_NO_THR */
UDATA VMCALL gpProtectedMain PROTOTYPE ((struct haCmdlineOptions * args));
IDATA convertString
PROTOTYPE ((JNIEnv * env, HyPortLibrary * portLibrary, jclass stringClass,
jmethodID stringMid, char *chars, jstring * str));
int arrangeToolsArgs
PROTOTYPE ((HyPortLibrary * portLibrary, int *pargc, char ***pargv, char *mainClass));
int augmentToolsArgs
PROTOTYPE ((HyPortLibrary * portLibrary, int *argc, char ***argv));
static IDATA addDirsToPath
#ifndef HY_NO_THR
PROTOTYPE ((HyPortLibrary * portLibrary, int count, char *newPathToAdd[], char **argv));
#else /* HY_NO_THR */
PROTOTYPE ((int count, char *newPathToAdd[], char **argv));
#endif /* HY_NO_THR */
int main_runJavaMain
PROTOTYPE ((JNIEnv * env, char *mainClassName, int nameIsUTF, int java_argc,
char **java_argv, HyPortLibrary * portLibrary));
static I_32 initDefaultDefines
PROTOTYPE ((HyPortLibrary * portLib, void **vmOptionsTable, int argc,
char **argv, int jarArg, HyStringBuffer ** classPathInd,
HyStringBuffer ** javaHomeInd,
HyStringBuffer ** javaLibraryPathInd,
char *vmdllsubdir, int *vmOptionsCount));
void
printUsageMessage(HyPortLibrary * portLibrary)
{
PORT_ACCESS_FROM_PORT (portLibrary);
hyfile_printf (PORTLIB, HYPORT_TTY_OUT, "Harmony Java launcher\n");
hyfile_printf (PORTLIB, HYPORT_TTY_OUT, HY_COPYRIGHT_STRING "\n");
hyfile_printf (PORTLIB, HYPORT_TTY_OUT,
"java [-vm:vmdll -vmdir:dir -D... [-X...]] [args]\n");
}
/**
* The actual main function wrapped in the standard GP-handler.
*
* @param[in] args The encapsulated command-line arguments and port library.
*
* @return 0 on success, or a non-zero error code on failure.
*/
UDATA VMCALL
gpProtectedMain (struct haCmdlineOptions *args)
{
int argc = args->argc;
char **argv = args->argv;
char *vmdll;
char *mainClass = NULL;
char *mainClassAlloc = NULL;
int isStandaloneJar = 0;
int copyrightWritten = 0;
int versionWritten = 0;
UDATA classArg = argc;
int i;
char *vmdllsubdir;
char *vmiPath = NULL;
char *newPathToAdd = NULL;
char *propertiesFileName = NULL;
char *exeName = NULL;
char *exeBaseName;
char *endPathPtr;
UDATA handle;
int javaRc = 0;
char defaultDllName[] = "harmonyvm";
char defaultDirName[] = "default";
int rc = -1;
int versionFlag = 0;
int vmHelp = 0;
int genericLauncher = 0;
char *str;
char *knownGenericNames[] = { "java", "java.exe", "javaw.exe", NULL };
#ifndef HY_NO_THR
char *dirs[2];
#endif /* ! HY_NO_THR */
PORT_ACCESS_FROM_PORT (args->portLibrary);
/* Find out name of the executable we are running as */
hysysinfo_get_executable_name (argv[0], &exeName);
/* Pick out the end of the exe path, and start of the basename */
exeBaseName = strrchr(exeName, DIR_SEPARATOR);
if (exeBaseName == NULL) {
endPathPtr = exeBaseName = exeName;
} else {
exeBaseName += 1;
endPathPtr = exeBaseName;
}
/* Test whether we are likely the generic java launcher (or a tool) */
i = 0;
str = knownGenericNames[i];
while(str != NULL) {
genericLauncher = (0 == strcmp (str, exeBaseName));
if (genericLauncher) {
break;
} else {
str = knownGenericNames[++i];
}
}
/* If we have a tool name we still may be execv'd so check for the orig
* command line arg.
*/
if (!genericLauncher) {
for (i = 1; i < argc; i++) {
if (0 == strcmp (argv[i], HY_TOOLS_PROP)) {
genericLauncher = 1;
break;
}
}
}
/* Now we know whether we are running as the original invocation of a tool,
* or a generic launcher / tool execv
*/
if (genericLauncher) {
/* The generic launcher needs at least one argument, otherwise
* print out a usage message.
*
* $$$ GMJ : TODO - rethink this - if a user types "java", they should
* get the standard java help dump, not some stuff about a launcher, as
* they thought they were running Java...
*/
if (argc <= 1) {
printUsageMessage(PORTLIB);
goto bail;
}
/* We are the generic launcher, figure out if we have a main class
* to run (the first argument that does not start with a '-', or if we
* have a '-jar' argument.
*/
for (i = 1; i < argc; i++) {
if ((0 == strcmp ("-help", argv[i])) ||
(0 == strcmp ("-h", argv[i])) ||
(0 == strcmp ("-?", argv[i])) ||
(0 == strcmp ("-X", argv[i]))) {
vmHelp = 1;
}
if ((0 == strcmp ("-cp", argv[i])) ||
(0 == strcmp ("-classpath", argv[i]))) {
/* Skip the classpath argument while looking for main class */
i++;
continue;
}
if (0 == strcmp ("-jar", argv[i])) {
/* The arg is a JAR file to run */
isStandaloneJar = 1;
}
if (0 == strncmp ("-version", argv[i], 8)) {
/* Display version information */
versionFlag = i;
}
if (0 == strncmp ("-showversion", argv[i], 12)) {
/* We are being asked to print our version and continue */
if (!versionFlag) versionFlag = i;
}
if ('-' != argv[i][0]) {
/* This is the main class */
classArg = i; /* save position */
mainClass = argv[i]; /* save class to execute */
break;
}
} /* end for-loop */
} else {
/* We are a tool launcher: main class deduced from exe name */
mainClass = hymem_allocate_memory (
strlen(HY_TOOLS_PACKAGE) + strlen(exeBaseName) + strlen (HY_TOOLS_MAIN_TYPE) + 3);
if (mainClass == NULL) {
/* HYNLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY=Internal VM error: Out of memory\n */
PORTLIB->nls_printf (PORTLIB, HYNLS_ERROR, HYNLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY);
goto bail;
} else {
/* Remember that we malloc'ed this mainClass space so we can free it */
mainClassAlloc = mainClass;
}
strcpy (mainClass, HY_TOOLS_PACKAGE);
strcat (mainClass, ".");
if (NULL == (str = strchr (exeBaseName, '.'))) {
strcat (mainClass, exeBaseName);
strcat (mainClass, ".");
} else {
strncat (mainClass, exeBaseName, (str - exeBaseName + 1));
}
strcat (mainClass, HY_TOOLS_MAIN_TYPE);
/* Useful when debugging */
/* hytty_printf(PORTLIB, "Before...\n");
* for (i=0; i<argc; i++) {
* hytty_printf(PORTLIB, "i=%d, v=%s\n", i, argv[i]);
* }
*/
/* Now ensure tools JAR is on classpath */
augmentToolsArgs(args->portLibrary, &argc, &argv);
classArg = arrangeToolsArgs(args->portLibrary, &argc, &argv, mainClass);
}
if (mainClass == NULL && !isStandaloneJar && !versionFlag && !vmHelp) {
printUsageMessage(PORTLIB);
goto bail;
}
/* Useful when debugging */
/* hytty_printf(PORTLIB, "After...\n");
* for (i=0; i<argc; i++) {
* hytty_printf(PORTLIB, "i=%d, v=%s\n", i, argv[i]);
* }
*/
/* At this point we either have a main class or know that we are running a JAR */
/* Find the vm dll */
vmdll = vmdll_parseCmdLine (PORTLIB, argc - 1, argv);
if (!vmdll) {
vmdll = defaultDllName;
}
/* Find the directory of the dll and set up the path */
#ifndef HY_NO_THR
vmdllsubdir = vmdlldir_parseCmdLine (PORTLIB, argc - 1, argv);
#else /* HY_NO_THR */
vmdllsubdir = vmdlldir_parseCmdLine (argc - 1, argv);
#endif /* HY_NO_THR */
if (!vmdllsubdir) {
vmdllsubdir = defaultDirName;
}
/* jvm dlls are located in a subdirectory off of jre/bin */
/* setup path to dll named in -vm argument */
endPathPtr[0] = '\0';
newPathToAdd = hymem_allocate_memory (strlen (exeName) + strlen (vmdllsubdir) + 1);
if (newPathToAdd == NULL) {
/* HYNLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY=Internal VM error: Out of memory\n */
PORTLIB->nls_printf (PORTLIB, HYNLS_ERROR,
HYNLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY);
goto bail;
}
vmiPath =
hymem_allocate_memory (strlen (exeName) + strlen (vmdllsubdir) +
strlen (vmdll) +
strlen (DIR_SEPARATOR_STR) + 1);
if (vmiPath == NULL)
{
/* HYNLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY=Internal VM error: Out of memory\n */
PORTLIB->nls_printf (PORTLIB, HYNLS_ERROR,
HYNLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY);
goto bail;
}
vmiPath[0] = '\0';
strcpy (newPathToAdd, exeName);
strcat (newPathToAdd, vmdllsubdir);
strcpy (vmiPath, newPathToAdd);
strcat (vmiPath, DIR_SEPARATOR_STR);
strcat (vmiPath, vmdll);
#ifndef HY_NO_THR
dirs[0] = newPathToAdd;
dirs[1] = exeName;
rc = addDirsToPath(PORTLIB, 2, dirs, argv);
if (rc == -1)
{
hytty_printf (PORTLIB, "addDirsToPath Failed\n");
goto bail;
}
#endif /* ! HY_NO_THR */
/* set up the properties file */
propertiesFileName = hymem_allocate_memory (strlen (vmiPath) + 12);
if (propertiesFileName == NULL)
{
/* HYNLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY=Internal VM error: Out of memory\n */
PORTLIB->nls_printf (PORTLIB, HYNLS_ERROR,
HYNLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY);
goto bail;
}
strcpy (propertiesFileName, vmiPath);
strcat (propertiesFileName, ".properties");
/* Open the DLL */
if (hysl_open_shared_library (vmiPath, &handle, TRUE))
{
hytty_printf (PORTLIB, "Failed to open JVM DLL: %s (%s)\n", vmiPath,
hyerror_last_error_message ());
goto bail;
}
/* main launcher processing in this function */
rc = invocation
(PORTLIB, argc, argv, handle, JNI_VERSION_1_4, JNI_TRUE, mainClass,
classArg, propertiesFileName, isStandaloneJar, vmdllsubdir, versionFlag);
if (rc)
{
/* Print an error message except in the case where an uncaught Exception
has terminated the VM */
if (rc != 100)
{
hytty_printf (PORTLIB, "FAILED to invoke JVM.\n");
}
goto bail;
}
if (hysl_close_shared_library (handle))
{
hytty_printf (PORTLIB, "Failed to close JVM DLL: %s\n", argv[1]);
goto bail;
}
bail:
if (exeName) {
hymem_free_memory (exeName);
}
if (mainClassAlloc) {
hymem_free_memory (mainClassAlloc);
}
if (propertiesFileName) {
hymem_free_memory (propertiesFileName);
}
if (vmiPath) {
hymem_free_memory (vmiPath);
}
if (newPathToAdd) {
hymem_free_memory (newPathToAdd);
}
// error code should be equal to 1 because of compatibility
return rc == 0 ? 0 : 1;
}
/**
* Arrange the argument list so that -J options come before the main
* tools class, and tools options come after.
*/
int
arrangeToolsArgs (HyPortLibrary * portLibrary, int *pargc, char ***pargv, char *mainClass)
{
int argc = *pargc;
char **argv = *pargv;
char **newargv;
int i, rc;
int newargvPos;
PORT_ACCESS_FROM_PORT(portLibrary);
/* Make room for the main tools class and tools property */
newargv = hymem_allocate_memory ((argc + 2) * sizeof(pargv));
if (NULL == newargv) {
/* HYNLS_EXELIB_VM_STARTUP_ERR_OUT_OF_MEMORY=Internal VM error\: VM startup error: Out of memory\n */
portLibrary->nls_printf (portLibrary, HYNLS_ERROR,
HYNLS_EXELIB_VM_STARTUP_ERR_OUT_OF_MEMORY);
hytty_err_printf (PORTLIB, "Failed to allocate more memory for tools args\n");
return 1;
}
/* Keep the exe name in position zero */
newargvPos = 0;
newargv[newargvPos++] = argv[0];
/* Copy any -J arguments to the left hand side of the main class */
for (i = 1; i < argc; i++) {
if (0 == strncmp (argv[i], "-J", 2)) {
newargv[newargvPos++] = argv[i] + 2; /* Remove the -J */
/* if it was specifying the classpath, take the next arg across too */
if ((0 == strncmp(argv[i], "-J-cp", 5)) ||
(0 == strncmp(argv[i], "-J-classpath", 12))) {
newargv[newargvPos++] = argv[++i];
}
}
}
/* Insert the command line */
newargv[newargvPos++] = HY_TOOLS_PROP;
/* Insert the tools main class */
rc = newargvPos; /* We will return this position to the caller */
newargv[newargvPos++] = mainClass;
/* Now copy remaining arguments to the right hand side of the main class */
for (i = 1; i < argc; i++) {
if (0 != strncmp (argv[i], "-J", 2)) {
newargv[newargvPos++] = argv[i];
} else {
/* Remember to ignore classpath args */
if ((0 == strncmp(argv[i], "-J-cp", 5)) ||
(0 == strncmp(argv[i], "-J-classpath", 12))) {
i++;
}
}
}
newargv[newargvPos] = NULL;
*pargc +=2;
*pargv = newargv;
return rc;
}
/**
* Add the tools.jar to the application classpath.
*/
int
augmentToolsArgs (HyPortLibrary * portLibrary, int *pargc, char ***pargv)
{
int argc = *pargc;
char **argv = *pargv;
char **newargv;
int i;
U_16 separator;
char *classpath;
char *newClasspath;
int classpathLen;
PORT_ACCESS_FROM_PORT(portLibrary);
/* If there is already a classpath argument, we add our tools to it */
for (i = 1; i < argc; i++) {
if ((0 == strncmp (argv[i], "-J-cp", 5)) ||
(0 == strncmp (argv[i], "-J-classpath", 12))) {
classpath = argv[++i];
if (NULL == classpath) {
return 1;
}
classpathLen = strlen (classpath);
separator = hysysinfo_get_classpathSeparator();
newClasspath = hymem_allocate_memory (
classpathLen + sizeof(separator) + strlen (HY_TOOLS_PATH) + 1);
if (NULL == newClasspath) {
/* HYNLS_EXELIB_VM_STARTUP_ERR_OUT_OF_MEMORY=Internal VM error\: VM startup error: Out of memory\n */
portLibrary->nls_printf (portLibrary, HYNLS_ERROR,
HYNLS_EXELIB_VM_STARTUP_ERR_OUT_OF_MEMORY);
hytty_err_printf (PORTLIB, "Failed to allocate memory for tools path\n");
return 1;
}
strcpy (newClasspath, classpath);
newClasspath[classpathLen++] = (char)(separator & 0xFF);
newClasspath[classpathLen] = '\0';
strcat(newClasspath, HY_TOOLS_PATH);
argv[i] = newClasspath;
return 0;
}
}
/* There was no classpath defined, so add one */
newargv = hymem_allocate_memory ((argc + 2) * sizeof(pargv));
if (NULL == newargv) {
/* HYNLS_EXELIB_VM_STARTUP_ERR_OUT_OF_MEMORY=Internal VM error\: VM startup error: Out of memory\n */
portLibrary->nls_printf (portLibrary, HYNLS_ERROR,
HYNLS_EXELIB_VM_STARTUP_ERR_OUT_OF_MEMORY);
hytty_err_printf (PORTLIB, "Failed to allocate more memory for tools path\n");
return 1;
}
for (i = 0; i < argc; i++) {
newargv[i] = argv[i];
}
newargv[i++]="-J-cp";
newargv[i++]=HY_TOOLS_PATH;
newargv[i]=NULL;
*pargc +=2;
*pargv = newargv;
return 0;
}
/**
* Scan for the -vm: option and return the associated value, or NULL
* if the argument cannot be found.
*/
char *VMCALL
vmdll_parseCmdLine (HyPortLibrary * portLibrary, UDATA lastLegalArg,
char **argv)
{
UDATA i;
/* Parse command line args for -vm: */
for (i = 1; i <= lastLegalArg; i++)
{
if ((argv[i][0] == '-'))
{
if ((PLATFORM_STRNICMP (&argv[i][1], "vm:", 3) == 0))
{
return &argv[i][4];
}
}
}
return NULL;
}
/**
* Scan for the -vmdir: option and return the associated value, or NULL
* if the argument cannot be found.
*/
char *VMCALL
#ifndef HY_NO_THR
vmdlldir_parseCmdLine (HyPortLibrary * portLibrary, UDATA lastLegalArg,
#else /* HY_NO_THR */
vmdlldir_parseCmdLine (UDATA lastLegalArg,
#endif /* HY_NO_THR */
char **argv)
{
UDATA i;
/* Parse command line args for -vmdir: */
for (i = 1; i <= lastLegalArg; i++)
{
if ((argv[i][0] == '-'))
{
if ((PLATFORM_STRNICMP (&argv[i][1], "vmdir:", 6) == 0))
{
return &argv[i][7];
}
}
}
return NULL;
}
/**
* Create of a JavaVM using JNI Invocation API and the arguments parsed from argc and argv.
* Run the java class
*
* @param[in] portLibrary The port library.
* @param[in] argc The number of arguments passed to program on the command line.
* @param[in] argv The values of command-line arguments.
* @param[in] handle The VM dll handle opened via the port library.
* @param[in] version The invocation API version to test.
* @param[in] ignoreUnrecognized A hint to the JNI to ignore/fail on unrecognized args.
* @param[in] mainClass The class to run.
* @param[in] classArg The index to mainClass in the array of launcher args.
* @param[in] propertiesFileName The properties file path and FileName.
*
* @return 0 on success, or a non-zero error code on failure.
*/
static int
invocation (HyPortLibrary * portLibrary, int argc, char **argv, UDATA handle,
jint version, jboolean ignoreUnrecognized, char *mainClass,
UDATA classArg, char *propertiesFileName,
int isStandaloneJar, char *vmdllsubdir, int versionFlag)
{
JavaVMInitArgs vm_args;
JavaVM *jvm;
JNIEnv *env;
char *mainClassJar;
int isNameUTF = 0;
int rc;
jint (JNICALL * CreateJavaVM) (JavaVM **, JNIEnv **, JavaVMInitArgs *);
PORT_ACCESS_FROM_PORT (portLibrary);
mainClassJar = NULL;
if (hysl_lookup_name
(handle, "JNI_CreateJavaVM", (UDATA *) &CreateJavaVM, "iLLL"))
{
hytty_printf (PORTLIB, "Failed to find JNI_CreateJavaVM in DLL\n");
return 1;
}
if (createVMArgs(portLibrary, argc, argv, version, ignoreUnrecognized,
&vm_args, classArg, propertiesFileName,
isStandaloneJar, &mainClassJar, vmdllsubdir)) {
return 1;
}
if (CreateJavaVM (&jvm, &env, &vm_args))
{
/* HYNLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_JAVA_VM=Internal VM error\: Failed to create Java VM\n */
portLibrary->nls_printf (portLibrary, HYNLS_ERROR,
HYNLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_JAVA_VM);
return 1;
}
rc = 0;
if (versionFlag) {
jclass clazz;
jmethodID mID;
jstring jStrObject;
/* First, print the copyright string to stdout */
hyfile_printf (PORTLIB, HYPORT_TTY_OUT, HY_COPYRIGHT_STRING "\n");
jStrObject = (*env)->NewStringUTF (env, argv[versionFlag]);
if (!jStrObject) return 3;
clazz = (*env)->FindClass (env, "org/apache/harmony/luni/util/Version");
if (!clazz) return 3;
mID = (*env)->GetStaticMethodID (env, clazz, "version",
"(Ljava/lang/String;)V");
if (!mID) return 3;
(*env)->CallStaticVoidMethod(env, clazz, mID, jStrObject);
/* if -version is specified, exit, otherwise continue */
if (0 == strncmp ("-version", argv[versionFlag], 8))
return 0;
}
if (mainClass)
{
if (isStandaloneJar)
{
//jclass jarRunner;
jclass clazz;
jmethodID mID;
jstring jStrObject;
mainClass = mainClassJar;
jStrObject = (*env)->NewStringUTF (env, mainClass);
if (!jStrObject)
{
rc = 3;
goto cleanup;
}
clazz = (*env)->FindClass (env, "java/lang/Class");
if (!clazz)
{
rc = 3;
goto cleanup;
}
mID =
(*env)->GetStaticMethodID (env, clazz, "forName",
"(Ljava/lang/String;)Ljava/lang/Class;");
if (!mID)
{
rc = 3;
goto cleanup;
}
/* ensure that the jar is the first arg passed to the jar runner */
classArg--;
/*
$$$ GMJ - removed this as it causes DRLVM to crash. Need to fix
DRLVM, but also have no idea why this is important - just seems
to be a test
jarRunner =
(*env)->CallStaticObjectMethod (env, clazz, mID, jStrObject);
if (jarRunner)
{
(*env)->DeleteLocalRef (env, jarRunner);
classArg -= 1; // make sure that the JAR is the first argument
}
else
{
(*env)->ExceptionClear (env);
(*jvm)->DestroyJavaVM (jvm);
rc = 3;
//goto cleanup;
}
*/
}
rc =
main_runJavaMain (env, mainClass, isNameUTF, (argc - (classArg + 1)),
&argv[classArg + 1], portLibrary);
}
cleanup:
if (vm_args.options)
{
hymem_free_memory (vm_args.options);
}
if (mainClassJar)
{
hymem_free_memory (mainClassJar);
}
/* Updated in the 6.0 spec, we can now detach the main thread before calling DestroyJavaVM,
and we must if we wish main thread uncaught exception handlers to be called. */
(*jvm)->DetachCurrentThread(jvm);
(*jvm)->DestroyJavaVM (jvm);
/*if ((*jvm)->DestroyJavaVM(jvm)) {
hytty_printf (PORTLIB, "Failed to destroy JVM\n");
return 1;
} */
return rc;
}
/**
* Converts command-line arguments into a format compatible with JNI invocation API.
*
* @param[in] portLibrary The port library.
* @param[in] argc The number of arguments passed to program on the command line.
* @param[in] argv The values of command-line arguments.
* @param[in] version The invocation API version to test.
* @param[in] ignoreUnrecognized A hint to the JNI to ignore/fail on unrecognized args.
* @param[in/out] vm_args Receives the newly converted JavaVMInitArgs (must be freed by caller).
* @param[in] classArg The index to mainClass in the array of launcher args.
* @param[in] propertiesFileName The properties file path and FileName.
* @param[out] mainClassJar The class to run if running Jar file.
*
* @return 0 on success, or a non-zero error code on failure.
*/
static int
createVMArgs (HyPortLibrary * portLibrary, int argc, char **argv,
jint version, jboolean ignoreUnrecognized,
JavaVMInitArgs * vm_args,
UDATA classArg, char *propertiesFileName,
int isStandaloneJar, char **mainClassJar, char *vmdllsubdir)
{
JavaVMOption *options;
char *exeName;
char *endPathPtr;
UDATA i;
unsigned int j;
unsigned int k;
unsigned int l;
key_value_pair * props = NULL;
U_32 propcount = 0;
unsigned int optcount = 0; /* number of specific options to VM */
char *classPath;
int vmJarRunner = -1; /* index of jarMainClass property */
int ignoreBCP = 0;
HyStringBuffer *javaHome = NULL, *classPath2 = NULL, *javaLibraryPath =
NULL;
char *portLibOptionStr = NULL;
static char* subst_items[] = {"%LAUNCHER_HOME%", "%VM_DIR%"};
static size_t subst_item_lens[] = {15, 8};
static unsigned int subst_num = 2;
char* subst_values[2];
size_t subst_value_lens[2];
PORT_ACCESS_FROM_PORT (portLibrary);
/* get the path to the executable */
hysysinfo_get_executable_name (argv[0], &exeName);
endPathPtr = strrchr (exeName, DIR_SEPARATOR);
endPathPtr[0] = '\0';
subst_values[0] = exeName;
subst_value_lens[0] = strlen(exeName);
subst_values[1] = vmdllsubdir ? vmdllsubdir : "";
subst_value_lens[1] = vmdllsubdir ? strlen(vmdllsubdir) : 0;
/* read in vm_args from properties file */
properties_load(portLibrary, propertiesFileName, &props, &propcount);
if (propcount != 0) {
/* Check if we need to filter "-Xbootclasspath" options out from properties. */
for (i = 1; i < classArg; i++)
{
if (strncmp (argv[i], "-Xbootclasspath:", 16) == 0) {
ignoreBCP = 1;
break;
}
}
}
for (l = 0; l < propcount; l++)
{
/* only pass arguments starting with '-' to JNI_CreateJavaVM */
if (props[l].key[0] == '-')
{
/* if running jar file there is special handling for java.class.path later */
/* Ignore classpath defines for -jar */
/* XXX -cp is accepted ??? */
/* if user overrides bootclasspath, skip bootclasspath defines */
if ( (isStandaloneJar && 0 == strncmp (props[l].key, "-Djava.class.path=", 18))
|| (ignoreBCP && 0 == strncmp (props[l].key, "-Xbootclasspath", 15)) )
{
props[l].key[0] = '\0';
continue;
}
++optcount;
}
else if (isStandaloneJar && 0 == strcmp(props[l].key, "jarMainClass"))
{
vmJarRunner = l;
}
}
if (isStandaloneJar)
{
char* runner = (vmJarRunner == -1) ?
HARMONY_JARRUNNER_CLASSNAME : props[vmJarRunner].value;
*mainClassJar = hymem_allocate_memory (strlen(runner) + 1);
if (*mainClassJar == NULL)
{
PORTLIB->nls_printf (PORTLIB, HYNLS_ERROR,
HYNLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY);
return 1;
}
strcpy (*mainClassJar, runner);
}
/* allocate space for entries from command line, properties file, */
/* 3 defaults plus the port library option */
options = hymem_allocate_memory((classArg + optcount + 4) * sizeof (*options));
if (options == NULL)
{
portLibrary->nls_printf (portLibrary, HYNLS_ERROR,
HYNLS_EXELIB_VM_STARTUP_ERR_OUT_OF_MEMORY);
hytty_err_printf (PORTLIB, "Failed to allocate memory for options\n");
return 1;
}
for (l = 0, j = 0; l < propcount; l++)
{
HyStringBuffer * lineBuf = NULL;
char *pos, *start;
int firstPass = 0;
if (props[l].key[0] != '-') {
continue;
}
/* format argument string as "key = value" */
start = pos = props[l].key;
do {
/* search & replace %XXX% in key and value, if any. */
while ( (pos = strchr(pos, '%')) )
{
int found = 0;
for (k = 0; k < subst_num; k++)
{
if (0 == strncmp(subst_items[k], pos, subst_item_lens[k])) {
*pos = '\0';
lineBuf = strBufferCat(PORTLIB, lineBuf, start);
*pos = '%';
lineBuf = strBufferCat(PORTLIB, lineBuf, subst_values[k]);
start = (pos += subst_item_lens[k]);
found = 1;
break;
}
}
if (!found) ++pos;
}
lineBuf = strBufferCat(PORTLIB, lineBuf, start);
/* key is processed in the first pass, check if we need next iteration. */
if (0 != firstPass++ || *props[l].value == '\0')
{
break;
}
lineBuf = strBufferCat(PORTLIB, lineBuf, "=");
start = pos = props[l].value;
}
while (1);
if (lineBuf == NULL) {
PORTLIB->nls_printf (PORTLIB, HYNLS_ERROR,
HYNLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY);
return 1;
}
/* FIXME: buffer leak ignored */
options[j].optionString = (char *)(lineBuf->data);
options[j].extraInfo = NULL;
++j;
}
properties_free(PORTLIB, props);
for (i = 1; i < classArg; i++)
{
if ( (strcmp (argv[i], "-jar") != 0)
&& (strncmp (argv[i], "-vmdir:", 7) != 0)
&& (strncmp (argv[i], "-vm:", 4) != 0)
&& (strncmp (argv[i], "-version", 8) != 0)
&& (strncmp (argv[i], "-showversion", 12) != 0))
{
/* special coding for -classpath and -cp */
/* they get passed to the vm as -Djava.class.path */
if ((strcmp (argv[i], "-cp") == 0)
|| (strcmp (argv[i], "-classpath") == 0))
{
classPath = hymem_allocate_memory (strlen (argv[i + 1]) + 20);
if (classPath == NULL)
{
/* HYNLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY=Internal VM error: Out of memory\n */
PORTLIB->nls_printf (PORTLIB, HYNLS_ERROR,
HYNLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY);
return 1;
}
//classPath = hymem_allocate_memory( 2048 );
strcpy (classPath, "-Djava.class.path=");
strcat (classPath, argv[i + 1]);
options[j].optionString = classPath;
i++; /*skip next arguement */
}
else if (strcmp(argv[i], "-verify")==0)
{
options[j].optionString="-Xverify";
}
else
{
options[j].optionString = argv[i];
}
options[j].extraInfo = NULL;
j++;
}
}
/* Check that the minimum required -D options have been included. If not, calculate and add the defaults */
initDefaultDefines (portLibrary, (void **)&options, argc, argv,
isStandaloneJar ? classArg : 0, &classPath2, &javaHome,
&javaLibraryPath, vmdllsubdir, (int *) &j);
// Slam in the pointer to the HyPortLibrary
portLibOptionStr = hymem_allocate_memory (strlen(PORT_LIB_OPTION) + 1);
if (portLibOptionStr == NULL)
{
/* HYNLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY=Internal VM error: Out of memory\n */
PORTLIB->nls_printf (PORTLIB, HYNLS_ERROR,
HYNLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY);
return 1;
}
strcpy (portLibOptionStr, PORT_LIB_OPTION);
options[j].optionString = portLibOptionStr;
options[j].extraInfo = portLibrary;
j++;
vm_args->version = version;
vm_args->nOptions = j;
vm_args->options = options;
vm_args->ignoreUnrecognized = ignoreUnrecognized;
// For debugging only
//printf ("JNI_CreateJavaVM no of args %d\n",vm_args->nOptions);
//for (j=0 ; j < (vm_args->nOptions) ; j++)
// {
// printf ("%s\n",vm_args->options[j]);
// }
return 0;
}
static BOOLEAN findDirInPath(char *path, char *dir, char *separator)
{
char *pos;
int pathlen;
int dirlen = strlen(dir);
while (dirlen > 1 && dir[dirlen-1] == DIR_SEPARATOR) {
dirlen--;
}
while ((pos = strchr(path, *separator)) != NULL) {
int savedpathlen = pathlen = pos - path;
while (pathlen > 1 && path[pathlen-1] == DIR_SEPARATOR) {
pathlen--;
}
if (dirlen == pathlen && !strncmp(path, dir, dirlen)) {
return TRUE;
}
path += savedpathlen + 1;
}
pathlen = strlen(path);
while (pathlen > 1 && path[pathlen-1] == DIR_SEPARATOR) {
pathlen--;
}
return dirlen == pathlen && !strncmp(path, dir, dirlen);
}
/**
* Update path to point to directory containing VM's DLLs
*
* @param[in] newPathToAdd The directory to add to the PATH environment variable
* @param[in] argv The commandline argv for linux
*
* return 0 on success, -1 on failure
*
*/
static IDATA
#ifndef HY_NO_THR
addDirsToPath (HyPortLibrary * portLibrary, int count, char *newPathToAdd[], char **argv)
#else /* HY_NO_THR */
addDirsToPath (int count, char *newPathToAdd[], char **argv)
#endif /* HY_NO_THR */
{
char *oldPath = NULL;
char *variableName = NULL;
char *separator = NULL;
char *newPath;
int rc = 0;
char *exeName;
int found = 0;
int i = 0;
int strLen = 0;
#ifndef HY_NO_THR
PORT_ACCESS_FROM_PORT (portLibrary);
hysysinfo_get_executable_name (argv[0], &exeName);
#else /* HY_NO_THR */
main_get_executable_name (argv[0], &exeName);
#endif /* HY_NO_THR */
variableName = LIBPATH_ENV_VAR;
separator = PATH_SEPARATOR_STR;
oldPath = getenv (variableName);
if (!oldPath) {
oldPath = "";
}
/*
* see if we can find all paths in the current path
*/
for (i=0; i < count; i++) {
if (newPathToAdd[i] != NULL) {
if (findDirInPath(oldPath, newPathToAdd[i], separator) != 0) {
found++;
} else {
strLen += strlen(newPathToAdd[i]) + 1;
}
}
}
/*
* if we found them all, we're done
*/
if (found == count) {
return 0;
}
/*
* now add the ones that the oldPath doesn't have. First figure out the
* size overall, and then add what we want on the front (keep the search
* short) and then add the old path on the end
*/
strLen += strlen(variableName) + strlen("=") + strlen(oldPath);
#ifndef HY_NO_THR
newPath = hymem_allocate_memory(strLen + 1);
#else /* HY_NO_THR */
newPath = main_mem_allocate_memory(strLen + 1);
#endif /* HY_NO_THR */
strcpy (newPath, variableName);
strcat (newPath, "=");
for (i=0; i < count; i++) {
if (newPathToAdd[i] != NULL
&& findDirInPath(oldPath, newPathToAdd[i], separator) == 0) {
strcat(newPath, newPathToAdd[i]);
strcat(newPath, separator);
}
}
strcat(newPath, oldPath);
/*
* now set the new path, and in case of !Windows, execv() to
* restart. Don't free newPath, as the docs say that the
* string becomes part of the environment, which sounds nutty
* but at worst, it's a leak of of one string under windows
*/
#if defined(WIN32)
rc = _putenv (newPath);
#else
rc = putenv (newPath);
execv (exeName, argv);
#endif
return rc;
}
int
main_runJavaMain (JNIEnv * env, char *mainClassName, int nameIsUTF,
int java_argc, char **java_argv,
HyPortLibrary * portLibrary)
{
int i, rc = 0;
jclass cls;
jmethodID mid, stringMid;
jarray args;
jclass stringClass;
char *slashifiedClassName, *dots, *slashes;
const char *utfClassName;
jboolean isCopy;
jstring str;
jclass globalCls;
jarray globalArgs;
PORT_ACCESS_FROM_PORT (portLibrary);
slashifiedClassName =
portLibrary->mem_allocate_memory (portLibrary,
strlen (mainClassName) + 1);
if (slashifiedClassName == NULL)
{
/* HYNLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY=Internal VM error: Out of memory\n */
portLibrary->nls_printf (portLibrary, HYNLS_ERROR,
HYNLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY);
rc = 2;
goto done;
}
for (slashes = slashifiedClassName, dots = mainClassName; *dots;
dots++, slashes++)
{
*slashes = (*dots == '.' ? '/' : *dots);
}
*slashes = '\0';
/* fetch j.l.String and the constructor that takes a byte array as parm */
stringClass = (*env)->FindClass (env, "java/lang/String");
if (!stringClass)
{
/* HYNLS_EXELIB_INTERNAL_VM_ERR_FAILED_TO_FIND_JLS=Internal VM error: Failed to find class java/lang/String\n */
portLibrary->nls_printf (portLibrary, HYNLS_ERROR,
HYNLS_EXELIB_INTERNAL_VM_ERR_FAILED_TO_FIND_JLS);
rc = 5;
goto done;
}
stringMid = ((*env)->GetMethodID (env, stringClass, "<init>", "([BII)V"));
#ifndef ZOS /* Only do UTF conversion on non-z/OS platforms*/
if (nameIsUTF)
#endif /* !ZOS */
{
cls = (*env)->FindClass (env, slashifiedClassName);
portLibrary->mem_free_memory (portLibrary, slashifiedClassName);
}
#ifndef ZOS
else
{
rc =
convertString (env, portLibrary, stringClass, stringMid,
slashifiedClassName, &str);
portLibrary->mem_free_memory (portLibrary, slashifiedClassName);
if (rc == 1)
{
/* HYNLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_BA=Internal VM error: Failed to create byte array for class name %s\n */
portLibrary->nls_printf (portLibrary, HYNLS_ERROR,
HYNLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_BA,
mainClassName);
rc = 10;
goto done;
}
if (rc == 2)
{
/* HYNLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_JLS_FOR_CLASSNAME=Internal VM error: Failed to create java/lang/String for class name %s\n */
portLibrary->nls_printf (portLibrary, HYNLS_ERROR,
HYNLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_JLS_FOR_CLASSNAME,
mainClassName);
rc = 11;
goto done;
}
utfClassName = (*env)->GetStringUTFChars (env, str, &isCopy);
if (utfClassName == NULL)
{
/* HYNLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY_CONVERTING=Internal VM error: Out of memory converting string to UTF Chars for class name %s\n */
portLibrary->nls_printf (portLibrary, HYNLS_ERROR,
HYNLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY_CONVERTING,
mainClassName);
rc = 12;
goto done;
}
cls = (*env)->FindClass (env, utfClassName);
(*env)->ReleaseStringUTFChars (env, str, utfClassName);
(*env)->DeleteLocalRef (env, str);
}
#endif /* !ZOS */
if (!cls)
{
rc = 3;
goto done;
}
/* Create the String array before getting the methodID to get better performance from HOOK_ABOUT_TO_RUN_MAIN */
args = (*env)->NewObjectArray (env, java_argc, stringClass, NULL);
if (!args)
{
/* HYNLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_ARG_ARRAY=Internal VM error: Failed to create argument array\n */
portLibrary->nls_printf (portLibrary, HYNLS_ERROR,
HYNLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_ARG_ARRAY);
rc = 6;
goto done;
}
for (i = 0; i < java_argc; ++i)
{
#ifndef ZOS /* Only convert the option strings on non-zOS platforms */
rc =
convertString (env, portLibrary, stringClass, stringMid, java_argv[i],
&str);
if (rc == 1)
{
/* HYNLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_BYTE_ARRAY=Internal VM error: Failed to create byte array for argument %s\n */
portLibrary->nls_printf (portLibrary, HYNLS_ERROR,
HYNLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_BYTE_ARRAY,
java_argv[i]);
rc = 7;
goto done;
}
if (rc == 2)
{
/* HYNLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_JLS_FOR_ARG=Internal VM error: Failed to create java/lang/String for argument %s\n */
portLibrary->nls_printf (portLibrary, HYNLS_ERROR,
HYNLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_JLS_FOR_ARG,
java_argv[i]);
rc = 8;
goto done;
}
(*env)->SetObjectArrayElement (env, args, i, str);
#else
(*env)->SetObjectArrayElement (env, args, i, (*env)->NewStringUTF(env, java_argv[i]));
#endif /* !ZOS */
if ((*env)->ExceptionCheck (env))
{
/* HYNLS_EXELIB_INTERNAL_VM_ERR_FAILED_SET_ARRAY_ELEM=Internal VM error: Failed to set array element for %s\n */
portLibrary->nls_printf (portLibrary, HYNLS_ERROR,
HYNLS_EXELIB_INTERNAL_VM_ERR_FAILED_SET_ARRAY_ELEM,
java_argv[i]);
rc = 9;
goto done;
}
#ifndef ZOS
(*env)->DeleteLocalRef (env, str);
#endif /* !ZOS */
}
mid =
(*env)->GetStaticMethodID (env, cls, "main", "([Ljava/lang/String;)V");
if (!mid)
{
/* Currently, GetStaticMethodID does not throw an exception when the method is not found */
/* HYNLS_EXELIB_CLASS_DOES_NOT_IMPL_MAIN=Class %s does not implement main()\n */
portLibrary->nls_printf (portLibrary, HYNLS_ERROR,
HYNLS_EXELIB_CLASS_DOES_NOT_IMPL_MAIN,
mainClassName);
rc = 4;
goto done;
}
globalCls = (jclass) (*env)->NewGlobalRef (env, cls);
if (globalCls)
{
(*env)->DeleteLocalRef (env, cls);
cls = globalCls;
}
globalArgs = (jarray) (*env)->NewGlobalRef (env, args);
if (globalArgs)
{
(*env)->DeleteLocalRef (env, args);
args = globalArgs;
}
(*env)->DeleteLocalRef (env, stringClass);
(*env)->CallStaticVoidMethod (env, cls, mid, args);
done:
if ((*env)->ExceptionCheck (env))
{
if (rc == 0)
rc = 100;
}
return rc;
}
void
dumpVersionInfo (HyPortLibrary * portLib)
{
PORT_ACCESS_FROM_PORT (portLib);
hytty_err_printf (PORTLIB,
(char *) portLib->nls_lookup_message (PORTLIB,
HYNLS_DO_NOT_PRINT_MESSAGE_TAG,
HYNLS_EXELIB_VERSION,
"\njava version 1.5 (subset)\n"), "1.5 (subset)\n");
}
static I_32
initDefaultDefines (HyPortLibrary * portLib, void **vmOptionsTable, int argc,
char **argv, int jarArg, HyStringBuffer ** classPathInd,
HyStringBuffer ** javaHomeInd,
HyStringBuffer ** javaLibraryPathInd,
char *vmdllsubdir, int *vmOptionsCount)
{
extern char *getDefineArgument (char *, char *);
int optionCount, i;
JavaVMOption *options;
int hasJavaHome = 0;
int hasJavaLibraryPath = 0;
int hasClassPath = 0;
HyStringBuffer *classPath = NULL;
HyStringBuffer *javaHome = NULL;
HyStringBuffer *javaLibraryPath = NULL;
/* Cycle through the list of VM options and check that the minimum required defaults are there.
* Calculate and insert the missing ones
*/
optionCount = *vmOptionsCount;
options = *vmOptionsTable;
for (i = 0; i < optionCount; i++)
{
if (getDefineArgument (options[i].optionString, "java.home"))
{
hasJavaHome = 1;
continue;
}
if (getDefineArgument (options[i].optionString, "java.library.path"))
{
hasJavaLibraryPath = 1;
continue;
}
if (getDefineArgument (options[i].optionString, "java.class.path"))
{
/* Ignore classpath defines for -jar */
if (!jarArg)
{
hasClassPath = 1;
continue;
}
}
}
if (!hasJavaHome)
{
if (0 != main_initializeJavaHome (portLib, &javaHome, argc, argv))
{
/* This might be a memory leak, but main() will fail anyway */
return -1;
}
if (javaHome)
{
javaHome = strBufferPrepend (portLib, javaHome, "-Djava.home=");
if (!javaHome)
return -1;
*javaHomeInd = javaHome;
options[*vmOptionsCount].optionString = (char *) javaHome->data;
options[*vmOptionsCount].extraInfo = NULL;
*vmOptionsCount = *vmOptionsCount + 1;
}
}
if (!hasJavaLibraryPath)
{
if (0 !=
main_initializeJavaLibraryPath (portLib, &javaLibraryPath, argv[0]))
{
/* This might be a memory leak, but main() will fail anyway */
return -1;
}
if (javaLibraryPath)
{
javaLibraryPath =
strBufferPrepend (portLib, javaLibraryPath,
"-Djava.library.path=");
if (!javaLibraryPath)
return -1;
*javaLibraryPathInd = javaLibraryPath;
options[*vmOptionsCount].optionString =
(char *) javaLibraryPath->data;
options[*vmOptionsCount].extraInfo = NULL;
*vmOptionsCount = *vmOptionsCount + 1;
}
}
if (!hasClassPath)
{
/* no free classpath if there is a -jar */
if (jarArg)
{
if (jarArg < argc)
{
classPath = strBufferCat (portLib, classPath, argv[jarArg]);
if (classPath == NULL)
return -1;
}
}
else
{
if (0 != main_initializeClassPath (portLib, &classPath))
{
/* This might be a memory leak, but main() will fail anyway */
return -1;
}
if (classPath == NULL || classPath->data[0] == 0)
{
classPath = strBufferCat (portLib, classPath, ".");
if (classPath == NULL)
return -1;
}
}
classPath = strBufferPrepend (portLib, classPath, "-Djava.class.path=");
if (classPath == NULL)
return -1;
*classPathInd = classPath;
options[*vmOptionsCount].optionString = (char *) classPath->data;
options[*vmOptionsCount].extraInfo = NULL;
*vmOptionsCount = *vmOptionsCount + 1;
}
return 0;
}
/* parse arg to determine if it is of the form -Darg=foo, and return foo.
* Returns an empty string for args of the form -Darg,
* Returns NULL if the argument is not recognized
*/
char *
getDefineArgument (char *arg, char *key)
{
if (arg[0] == '-' && arg[1] == 'D')
{
int keyLength = strlen (key);
if (strncmp (&arg[2], key, keyLength) == 0)
{
switch (arg[2 + keyLength])
{
case '=':
return &arg[3 + keyLength];
case '\0':
return "";
}
}
}
return NULL;
}
#ifdef HY_NO_THR
int
main_addVMDirToPath(int argc, char **argv, char **envp)
{
char *vmdllsubdir;
char *newPathToAdd = NULL;
char *propertiesFileName = NULL;
char *exeName = NULL;
char *exeBaseName;
char *endPathPtr;
char defaultDirName[] = "default";
int rc = -1;
char *dirs[2];
/* Find out name of the executable we are running as */
main_get_executable_name (argv[0], &exeName);
/* Pick out the end of the exe path, and start of the basename */
exeBaseName = strrchr(exeName, DIR_SEPARATOR);
if (exeBaseName == NULL) {
endPathPtr = exeBaseName = exeName;
} else {
exeBaseName += 1;
endPathPtr = exeBaseName;
}
/* Find the directory of the dll and set up the path */
vmdllsubdir = vmdlldir_parseCmdLine (argc - 1, argv);
if (!vmdllsubdir) {
vmdllsubdir = defaultDirName;
}
/* jvm dlls are located in a subdirectory off of jre/bin */
/* setup path to dll named in -vm argument */
endPathPtr[0] = '\0';
newPathToAdd = main_mem_allocate_memory (strlen (exeName) + strlen (vmdllsubdir) + 1);
if (newPathToAdd == NULL) {
goto bail;
}
strcpy (newPathToAdd, exeName);
strcat (newPathToAdd, vmdllsubdir);
dirs[0] = newPathToAdd;
dirs[1] = exeName;
rc = addDirsToPath(2, dirs, argv);
bail:
if (exeName) {
main_mem_free_memory (exeName);
}
if (newPathToAdd) {
main_mem_free_memory (newPathToAdd);
}
// error code should be equal to 1 because of compatibility
return rc == 0 ? 0 : 1;
}
#endif /* HY_NO_THR */