Path: blob/master/runtime/exelib/common/libhlp.c
6000 views
/*******************************************************************************1* Copyright (c) 1991, 2020 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/2122#include <stdlib.h>23#include <stdio.h>24#include <string.h>25#include "jni.h"26#include "j9user.h"27#include "j9port.h"28#include "cfr.h"29#include "j9.h"30#include "j9protos.h"31#include "rommeth.h"32#include "j9version.h"3334#include "libhlp.h"3536#include "j9exelibnls.h"37#include "exelib_internal.h"3839#define J9_PATH_SLASH DIR_SEPARATOR4041static IDATA convertString (JNIEnv* env, J9PortLibrary *j9portLibrary, jclass utilClass, jmethodID utilMid, char* chars, jstring* str);424344#define ROUND_TO_1K( x ) (((x + 1023) / 1024) * 1024)4546static char versionString[255];4748I_32 main_appendToClassPath( J9PortLibrary *portLib, U_16 sep, J9StringBuffer **classPath, char *toAppend) {4950/* append a separator, first */51if ((NULL != *classPath)52&& ((*classPath)->data[strlen((const char*)(*classPath)->data)] != sep)53) {54char separator[2];55separator[0] = (char)sep;56separator[1] = '\0';57*classPath = strBufferCat(portLib, *classPath, separator);58if (*classPath == NULL) return -1;59}6061*classPath = strBufferCat(portLib, *classPath, toAppend);62if (*classPath == NULL) return -1;6364return 0;65}6667686970IDATA main_initializeBootLibraryPath(J9PortLibrary * portLib, J9StringBuffer **finalBootLibraryPath, char *argv0)71{72*finalBootLibraryPath = NULL;73{74char *p = NULL;75char *bootLibraryPath = NULL;76PORT_ACCESS_FROM_PORT(portLib);7778if (j9sysinfo_get_executable_name (argv0, &bootLibraryPath)) {79return -1;80}8182p = strrchr(bootLibraryPath, J9_PATH_SLASH);83if (p) {84p[1] = '\0';85*finalBootLibraryPath = strBufferCat(portLib, NULL, bootLibraryPath);86}87/* Do /not/ delete executable name string; system-owned. */88}89return 0;90}91929394/* Allocates and retrieves initial value of the classPath. */9596I_32 main_initializeClassPath( J9PortLibrary *portLib, J9StringBuffer** classPath)97{98PORT_ACCESS_FROM_PORT( portLib );99IDATA rc;100char* envvars = "CLASSPATH\0classpath\0";101char* envvar;102103for (envvar = envvars; *envvar; envvar += strlen(envvar) + 1) {104rc = j9sysinfo_get_env(envvar, NULL, 0);105if (rc > 0) {106char * cpData = NULL;107*classPath = strBufferEnsure(portLib, *classPath, rc);108if (*classPath == NULL) return -1;109cpData = (*classPath)->data + strlen((const char*)(*classPath)->data);110j9sysinfo_get_env(envvar, cpData, rc);111(*classPath)->remaining -= rc;112break;113}114}115116return 0;117}118119120IDATA main_initializeJavaHome(J9PortLibrary * portLib, J9StringBuffer **finalJavaHome, int argc, char **argv)121{122char *javaHome = NULL;123char *javaHomeModifiablePart = NULL;124char *p;125IDATA retval = -1;126IDATA rc;127UDATA isUpper = TRUE;128char* envvars = "JAVA_HOME\0java_home\0";129char* envvar;130131PORT_ACCESS_FROM_PORT(portLib);132133#ifdef DEBUG134j9tty_printf(portLib, "initializeJavaHome called\n");135#endif136137for (envvar = envvars; *envvar; envvar += strlen(envvar) + 1) {138rc = j9sysinfo_get_env(envvar, NULL, 0);139if (rc > 0) {140char* javaHomeData = NULL;141*finalJavaHome = strBufferEnsure(PORTLIB, *finalJavaHome, rc);142if (NULL == *finalJavaHome) {143return -1;144}145javaHomeData = (*finalJavaHome)->data + strlen((const char*)(*finalJavaHome)->data);146j9sysinfo_get_env(envvar, javaHomeData , rc);147(*finalJavaHome)->remaining -= rc;148return 0;149}150}151152/* Compute the proper value for the var. */153154if ((argc < 1) || !argv) return -1;155156retval = j9sysinfo_get_executable_name(argv[0], &javaHome);157if (retval) {158*finalJavaHome = strBufferCat(PORTLIB, *finalJavaHome, "..");159return 0;160}161162javaHomeModifiablePart = javaHome;163#if defined(WIN32) || defined(OS2)164/* Make sure we don't modify a drive specifier in a pathname. */165if ((strlen(javaHome) > 2) && (javaHome[1] == ':')) {166javaHomeModifiablePart = javaHome + 2;167if (javaHome[2] == J9_PATH_SLASH)168javaHomeModifiablePart++;169}170#endif171#if defined(WIN32) || defined(OS2)172/* Make sure we don't modify the root of a UNC pathname. */173if ((strlen(javaHome) > 2) && (javaHome[0] == J9_PATH_SLASH) && (javaHome[1] == J9_PATH_SLASH)) {174javaHomeModifiablePart = javaHome + 2;175/* skip over the machine name */176while (*javaHomeModifiablePart && (*javaHomeModifiablePart != J9_PATH_SLASH)) {177javaHomeModifiablePart++;178}179if (*javaHomeModifiablePart)180javaHomeModifiablePart++;181/* skip over the share name */182while (*javaHomeModifiablePart && (*javaHomeModifiablePart != J9_PATH_SLASH)) {183javaHomeModifiablePart++;184}185}186#endif187if ((javaHomeModifiablePart == javaHome) && javaHome[0] == J9_PATH_SLASH) {188/* make sure we don't modify a root slash. */189javaHomeModifiablePart++;190}191192/* Note: if sysinfo_get_executable_name claims we were invoked from a root directory, */193/* then this code will return that root directory for java.home also. */194p = strrchr(javaHomeModifiablePart, J9_PATH_SLASH);195if (!p) {196javaHomeModifiablePart[0] = '\0'; /* chop off whole thing! */197} else {198p[0] = '\0'; /* chop off trailing slash and executable name. */199p = strrchr(javaHomeModifiablePart, J9_PATH_SLASH);200if (!p) {201javaHomeModifiablePart[0] = '\0'; /* chop off the rest */202} else {203p[0] = '\0'; /* chop off trailing slash and deepest subdirectory. */204}205}206207*finalJavaHome = strBufferCat(PORTLIB, *finalJavaHome, javaHome);208/* Do /not/ delete executable name string; system-owned. */209return 0;210}211212213214IDATA main_initializeJavaLibraryPath(J9PortLibrary * portLib, J9StringBuffer **finalJavaLibraryPath, char *argv0)215{216#ifdef WIN32217#define ENV_PATH "PATH"218#else219#if defined(AIXPPC)220#define ENV_PATH "LIBPATH"221#else222#define ENV_PATH "LD_LIBRARY_PATH"223#endif224#endif225226J9StringBuffer *javaLibraryPath = NULL;227char *exeName = NULL;228IDATA rc = -1;229char *p = NULL;230char *envResult = NULL;231IDATA envSize;232#define ENV_BUFFER_SIZE 80233char envBuffer[ENV_BUFFER_SIZE];234char sep[2];235PORT_ACCESS_FROM_PORT(portLib);236237sep[0] = (char)j9sysinfo_get_classpathSeparator();238sep[1] = '\0';239240if (j9sysinfo_get_executable_name(argv0, &exeName)) {241goto done;242}243p = strrchr(exeName, J9_PATH_SLASH);244if (NULL != p) {245p[1] = '\0';246} else {247/* Reset to NULL; do /not/ delete (system-owned string). */248exeName = NULL;249}250251envSize = j9sysinfo_get_env( ENV_PATH, NULL, 0 );252if( envSize > 0 ) {253if( envSize >= ENV_BUFFER_SIZE ) {254envResult = j9mem_allocate_memory( envSize + 1 , OMRMEM_CATEGORY_VM);255if (!envResult) goto done;256j9sysinfo_get_env( ENV_PATH, envResult, envSize );257} else {258envSize = -1; /* make it -1 so we don't free the buffer */259j9sysinfo_get_env( ENV_PATH, envBuffer, ENV_BUFFER_SIZE );260envResult = envBuffer;261}262} else {263envResult = NULL;264}265266267/* Add one to each length to account for the separator character. Add 2 at the end for the "." and NULL terminator */268269if (exeName) {270javaLibraryPath = strBufferCat(portLib, javaLibraryPath, exeName);271javaLibraryPath = strBufferCat(portLib, javaLibraryPath, sep);272}273javaLibraryPath = strBufferCat(portLib, javaLibraryPath, ".");274if (envResult) {275javaLibraryPath = strBufferCat(portLib, javaLibraryPath, sep);276javaLibraryPath = strBufferCat(portLib, javaLibraryPath, envResult);277if( envSize != -1 ) {278j9mem_free_memory( envResult );279}280}281282rc = 0;283284done:285/* Do /not/ delete executable name string; system-owned. */286*finalJavaLibraryPath = javaLibraryPath;287return rc;288}289290291292int main_runJavaMain(JNIEnv * env, char *mainClassName, int nameIsUTF, int java_argc, char **java_argv, J9PortLibrary * j9portLibrary)293{294int i, rc = 0;295jclass cls;296jmethodID mid, utilMid;297jarray args;298jclass utilClass, stringClass;299char *slashifiedClassName, *dots, *slashes;300const char *utfClassName;301jboolean isCopy;302jstring str;303jclass globalCls;304jarray globalArgs;305306PORT_ACCESS_FROM_PORT(j9portLibrary);307308slashifiedClassName = j9mem_allocate_memory(strlen(mainClassName) + 1, OMRMEM_CATEGORY_VM);309if (slashifiedClassName == NULL) {310/* J9NLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY=Internal VM error: Out of memory\n */311j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY);312rc = 2;313goto done;314}315for (slashes = slashifiedClassName, dots = mainClassName; *dots; dots++, slashes++) {316*slashes = (*dots == '.' ? '/' : *dots);317}318*slashes = '\0';319320/* These classes must have already been found as part of bootstrap */321stringClass = (*env)->FindClass(env, "java/lang/String");322if (!stringClass) {323/* J9NLS_EXELIB_INTERNAL_VM_ERR_FAILED_TO_FIND_JLS=Internal VM error: Failed to find class java/lang/String\n */324j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_EXELIB_INTERNAL_VM_ERR_FAILED_TO_FIND_JLS );325rc = 5;326goto done;327}328utilClass = (*env)->FindClass(env, "com/ibm/oti/util/Util");329if (NULL == utilClass) {330/* J9NLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_JLS_FOR_CLASSNAME=Internal VM error: Failed to create java/lang/String for class name %s\n */331j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_JLS_FOR_CLASSNAME, mainClassName);332rc = 13;333goto done;334}335utilMid = ((*env)->GetStaticMethodID(env, utilClass, "toString", "([BII)Ljava/lang/String;"));336if (NULL == utilMid) {337/* J9NLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_JLS_FOR_CLASSNAME=Internal VM error: Failed to create java/lang/String for class name %s\n */338j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_JLS_FOR_CLASSNAME, mainClassName);339rc = 14;340goto done;341}342343if(nameIsUTF) {344cls = (*env)->FindClass(env, slashifiedClassName);345j9mem_free_memory(slashifiedClassName);346} else {347IDATA rcConvert = convertString(env, j9portLibrary, utilClass, utilMid, slashifiedClassName, &str);348j9mem_free_memory(slashifiedClassName);349350if(rcConvert == 1) {351/* J9NLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_BA=Internal VM error: Failed to create byte array for class name %s\n */352j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_BA, mainClassName);353rc = 10;354goto done;355}356if(rcConvert == 2) {357/* J9NLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_JLS_FOR_CLASSNAME=Internal VM error: Failed to create java/lang/String for class name %s\n */358j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_JLS_FOR_CLASSNAME, mainClassName);359rc = 11;360goto done;361}362utfClassName = (const char *) (*env)->GetStringUTFChars(env, str, &isCopy);363if(utfClassName == NULL) {364/* J9NLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY_CONVERTING=Internal VM error: Out of memory converting string to UTF Chars for class name %s\n */365j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_EXELIB_INTERNAL_VM_ERR_OUT_OF_MEMORY_CONVERTING, mainClassName);366rc = 12;367goto done;368}369cls = (*env)->FindClass(env, utfClassName);370(*env)->ReleaseStringUTFChars(env, str, utfClassName);371(*env)->DeleteLocalRef(env, str);372}373374if (!cls) {375rc = 3;376goto done;377}378379/* Create the String array before getting the methodID to get better performance from HOOK_ABOUT_TO_RUN_MAIN */380args = (*env)->NewObjectArray(env, java_argc, stringClass, NULL);381if (!args) {382/* J9NLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_ARG_ARRAY=Internal VM error: Failed to create argument array\n */383j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_ARG_ARRAY);384rc = 6;385goto done;386}387for (i = 0; i < java_argc; ++i) {388IDATA rcConvert = convertString(env, j9portLibrary, utilClass, utilMid, java_argv[i], &str);389if(rcConvert == 1) {390/* J9NLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_BYTE_ARRAY=Internal VM error: Failed to create byte array for argument %s\n */391j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_BYTE_ARRAY, java_argv[i]);392rc = 7;393goto done;394}395if(rcConvert == 2) {396/* J9NLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_JLS_FOR_ARG=Internal VM error: Failed to create java/lang/String for argument %s\n*/397j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_EXELIB_INTERNAL_VM_ERR_FAILED_CREATE_JLS_FOR_ARG, java_argv[i]);398rc = 8;399goto done;400}401402(*env)->SetObjectArrayElement(env, args, i, str);403if ((*env)->ExceptionCheck(env)) {404/* J9NLS_EXELIB_INTERNAL_VM_ERR_FAILED_SET_ARRAY_ELEM=Internal VM error: Failed to set array element for %s\n */405j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_EXELIB_INTERNAL_VM_ERR_FAILED_SET_ARRAY_ELEM,406java_argv[i]);407rc = 9;408goto done;409}410(*env)->DeleteLocalRef(env, str);411}412413mid = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V");414if (!mid) {415/* Currently, GetStaticMethodID does not throw an exception when the method is not found */416/* J9NLS_EXELIB_CLASS_DOES_NOT_IMPL_MAIN=Class %s does not implement main()\n */417j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_EXELIB_CLASS_DOES_NOT_IMPL_MAIN, mainClassName);418rc = 4;419goto done;420}421/* For compliance purposes on CDC we must apply the spec more strictly than the JDK seems to */422/* Verify that the main method we found is public, static, and void -- as described in 2.17.1 of the spec */423/* WARNING: this is non-portable J9 specific code */424if( ((J9VMThread *)env)->javaVM->runtimeFlags & J9RuntimeFlagVerify ) {425J9ROMMethod *romMethod = J9_ROM_METHOD_FROM_RAM_METHOD( ((J9JNIMethodID *)mid)->method );426if( (romMethod->modifiers & (CFR_ACC_STATIC | CFR_ACC_PUBLIC)) != (CFR_ACC_STATIC | CFR_ACC_PUBLIC) ) {427/* J9NLS_EXELIB_MUST_BE_PSV=The method main must be declared public, static and void.\n */428j9nls_printf(PORTLIB, J9NLS_ERROR, J9NLS_EXELIB_MUST_BE_PSV);429rc = 4;430goto done;431}432} /* end of non-portable J9 specific code */433434globalCls = (jclass) (*env)->NewGlobalRef(env, cls);435if (globalCls) {436(*env)->DeleteLocalRef(env, cls);437cls = globalCls;438}439globalArgs = (jarray) (*env)->NewGlobalRef(env, args);440if (globalArgs) {441(*env)->DeleteLocalRef(env, args);442args = globalArgs;443}444(*env)->DeleteLocalRef(env, stringClass);445(*env)->CallStaticVoidMethod(env, cls, mid, args);446447done:448if ((*env)->ExceptionCheck(env)) {449if (rc == 0)450rc = 100;451}452453(*env)->ExceptionDescribe(env);454return rc;455}456457458459/* Compute and return a string which is the vm version */460461char * main_vmVersionString(void)462{463U_32 minorVersion;464char *native = "";465char *versionStringPtr = GLOBAL_DATA(versionString);466minorVersion = EsVersionMinor;467468if ((minorVersion % 10) == 0)469minorVersion /= 10;470sprintf (versionStringPtr, "%d.%d%s,%s %s",471EsVersionMajor, minorVersion, EsExtraVersionString, native, EsBuildVersionString);472return versionStringPtr;473}474475476477478static IDATA479convertString(JNIEnv* env, J9PortLibrary *j9portLibrary, jclass utilClass, jmethodID utilMid, char* chars, jstring* str)480{481jsize strLength;482jarray bytearray;483jstring string;484485strLength = (jsize) strlen(chars);486bytearray = (*env)->NewByteArray(env, strLength);487if (((*env)->ExceptionCheck(env))) {488return 1;489}490491(*env)->SetByteArrayRegion(env, bytearray, (UDATA)0, strLength, (jbyte*)chars);492493string = (*env)->CallStaticObjectMethod(env, utilClass, utilMid, bytearray, (jint)0, strLength);494(*env)->DeleteLocalRef(env, bytearray);495496if (!string) {497return 2;498} else {499*str = string;500return 0;501}502}503504505/* Compute and return a string which is the nitty-gritty for the vm */506507char * vmDetailString( J9PortLibrary *portLib, char *detailString, UDATA detailStringLength )508{509const char *ostype, *osversion, *osarch;510PORT_ACCESS_FROM_PORT( portLib );511512ostype = j9sysinfo_get_OS_type();513osversion = j9sysinfo_get_OS_version();514osarch = j9sysinfo_get_CPU_architecture();515516j9str_printf (PORTLIB, detailString, detailStringLength, "%s (%s %s %s)", EsBuildVersionString, ostype ? ostype : "unknown", osversion ? osversion : "unknown", osarch ? osarch : "unknown");517return detailString;518}519520521/* Try to initialize the NLS catalog; otherwise use defaults */522void main_setNLSCatalog(J9PortLibrary * portLib, char **argv)523{524char *exename = NULL;525526PORT_ACCESS_FROM_PORT(portLib);527528/* Locate 'lib' directory which contains java.properties file */529if ( j9sysinfo_get_executable_name( argv[0], &exename ) == 0 ) {530/* For Java 8, java.properties file is present at same location as 'exename',531* but for Java 9, java.properties is under 'lib' directory.532* Since we have no way to determine if we are running for Java 8 or Java 9,533* pass both the locations to j9nls_set_catalog() and let it search for the file.534*/535char *nlsPaths[] = { exename, NULL };536char *exe = NULL;537char *vmName = NULL;538UDATA exeNameLen = strlen(exename);539#ifdef WIN32540UDATA j9libLen = exeNameLen + strlen(DIR_SEPARATOR_STR) * 2 + strlen("lib") + 1;541char *j9lib = j9mem_allocate_memory(j9libLen, OMRMEM_CATEGORY_VM);542543if (NULL != j9lib) {544char *bin = NULL;545546strcpy(j9lib, exename);547548/* Remove exe name, VM name ('default' or 'compressedrefs') and 'bin', then add 'lib' */549exe = strrchr(j9lib, DIR_SEPARATOR);550if (NULL != exe) {551*exe = '\0';552}553vmName = strrchr(j9lib, DIR_SEPARATOR);554if (NULL != vmName) {555*vmName = '\0';556}557bin = strrchr(j9lib, DIR_SEPARATOR);558if (NULL != bin) {559*bin = '\0';560}561562/* j9nls_set_catalog ignores everything after the last slash. Append a slash to j9lib. */563strcat(j9lib, DIR_SEPARATOR_STR);564strcat(j9lib, "lib");565strcat(j9lib, DIR_SEPARATOR_STR);566#else567char *j9lib = j9mem_allocate_memory(exeNameLen + 1, OMRMEM_CATEGORY_VM);568569if (NULL != j9lib) {570strcpy(j9lib, exename);571572/* Remove exe name and VM name ('default' or 'compressedrefs') */573exe = strrchr(j9lib, DIR_SEPARATOR);574if (NULL != exe) {575*exe = '\0';576}577vmName = strrchr(j9lib, DIR_SEPARATOR);578if (NULL != vmName) {579*vmName = '\0';580}581/* leave the platform name, it gets removed by j9nls_set_catalog as it ignores everything after the last slash. */582#endif /* WIN32 */583nlsPaths[1] = j9lib;584}585j9nls_set_catalog( (const char**)nlsPaths, 2, "java", "properties" );586if (NULL != j9lib) {587j9mem_free_memory(j9lib);588}589}590/* Do /not/ delete executable name string; system-owned. */591}592593/*594* Returns a non-zero value if an error occurred, returns zero on success.595* If a default option file is located, optionFileName is an allocated buffer (must be freed by596* callee) that contains the fully qualified filename.597* If a default option file cannot be found, optionFileName will point at NULL.598*599*/600I_32 main_findDefaultOptionsFile( J9PortLibrary *portLib, char *argv0, char **optionFileName) {601char *exeName;602char *eptr;603char *ptr;604char *defaultOptionFileName;605IDATA file;606PORT_ACCESS_FROM_PORT(portLib);607608609if( j9sysinfo_get_executable_name(argv0, &exeName)) {610return -1;611}612defaultOptionFileName = j9mem_allocate_memory(strlen(exeName) + 6, OMRMEM_CATEGORY_VM); /* +6 == ".j9vm" + zero termination */613if(NULL == defaultOptionFileName ) {614return -1;615}616/* First look for <path>/.<exename> */617strcpy( defaultOptionFileName, exeName );618#if defined(WIN32)619/* On Windows we have to strip the .exe extension */620eptr = strrchr( exeName, '.');621if( eptr ) {622*eptr = '\0';623}624#endif625eptr = strrchr( exeName, DIR_SEPARATOR);626ptr = strrchr( defaultOptionFileName, DIR_SEPARATOR);627if( ptr ) { /* we can assume if ptr is valid, so is eptr */628ptr[1] = '.';629ptr[2] = '\0';630strcat( defaultOptionFileName, &eptr[1] );631file = j9file_open( defaultOptionFileName, EsOpenRead, 0);632if( file != -1 ) {633j9file_close(file);634*optionFileName = defaultOptionFileName;635/* Do /not/ delete executable name string; system-owned. */636return 0;637}638}639/* Do /not/ delete executable name string; system-owned. */640641ptr = strrchr( defaultOptionFileName, DIR_SEPARATOR);642if( ptr ) {643/* if we found a separator - truncate just after it */644ptr++;645*ptr = '\0';646strcat( defaultOptionFileName, ".j9vm" );647file = j9file_open( defaultOptionFileName, EsOpenRead, 0);648if( file != -1 ) {649j9file_close(file);650*optionFileName = defaultOptionFileName;651return 0;652}653}654/* No failure, but no file found */655*optionFileName = NULL;656j9mem_free_memory( defaultOptionFileName );657return 0;658}659660661