Index: shared/cmain.c =================================================================== --- shared/cmain.c (revision 501409) +++ shared/cmain.c (working copy) @@ -17,7 +17,9 @@ #include "hycomp.h" #include "hyport.h" +#include "main_hlp.h" #include /* for malloc for atoe and abort */ +#include struct haCmdlineOptions { @@ -27,6 +29,7 @@ HyPortLibrary *portLibrary; }; extern UDATA VMCALL gpProtectedMain (void *arg); +extern int main_addVMDirToPath(int argc, char **argv, char **envp); static UDATA VMCALL genericSignalHandler (struct HyPortLibrary *portLibrary, U_32 gpType, @@ -80,6 +83,10 @@ return gpProtectedMain (arg); } +typedef I_32 (PVMCALL hyport_init_library_type) (struct HyPortLibrary *portLibrary, + struct HyPortLibraryVersion *version, + UDATA size); + int main (int argc, char **argv, char **envp) { @@ -88,7 +95,23 @@ struct haCmdlineOptions options; int rc = 257; UDATA result; + UDATA portLibDescriptor; + hyport_init_library_type port_init_library_func; + + /* determine which VM directory to use and add it to the path */ + rc = main_addVMDirToPath(argc, argv, envp); + if ( 0 != rc ) { + return rc; + } + if ( 0 != main_open_port_library(&portLibDescriptor) ) { + fprintf( stderr, "failed to open hyprt library.\n" ); + return -1; + } + if ( 0 != main_lookup_name( portLibDescriptor, "hyport_init_library", (UDATA *)&port_init_library_func) ) { + fprintf( stderr, "failed to find hyport_init_library function in hyprt library\n" ); + return -1; + } /* Use portlibrary version which we compiled against, and have allocated space * for on the stack. This version may be different from the one in the linked DLL. */ @@ -94,7 +117,7 @@ */ HYPORT_SET_VERSION (&portLibraryVersion, HYPORT_CAPABILITY_MASK); if (0 == - hyport_init_library (&hyportLibrary, &portLibraryVersion, + port_init_library_func (&hyportLibrary, &portLibraryVersion, sizeof (HyPortLibrary))) { options.argc = argc; Index: shared/main.c =================================================================== --- shared/main.c (revision 501409) +++ shared/main.c (working copy) @@ -24,6 +24,7 @@ #include "hyexelibnls.h" /* nls strings */ #include "libhlp.h" /* defaults and environment variables and string buffer functions */ #include "strhelp.h" /* for properties file parsing */ +#include "main_hlp.h" /* plaftorm specific launcher helpers */ #include #include @@ -63,7 +64,7 @@ char *VMCALL vmdll_parseCmdLine PROTOTYPE ((HyPortLibrary * portLibrary, UDATA lastLegalArg, char **argv)); char *VMCALL vmdlldir_parseCmdLine -PROTOTYPE ((HyPortLibrary * portLibrary, UDATA lastLegalArg, char **argv)); +PROTOTYPE ((UDATA lastLegalArg, char **argv)); UDATA VMCALL gpProtectedMain PROTOTYPE ((struct haCmdlineOptions * args)); IDATA convertString PROTOTYPE ((JNIEnv * env, HyPortLibrary * portLibrary, jclass stringClass, @@ -73,7 +74,7 @@ int augmentToolsArgs PROTOTYPE ((HyPortLibrary * portLibrary, int *argc, char ***argv)); static IDATA addDirsToPath -PROTOTYPE ((HyPortLibrary * portLibrary, int count, char *newPathToAdd[], char **argv)); +PROTOTYPE ((int count, char *newPathToAdd[], char **argv)); int main_runJavaMain PROTOTYPE ((JNIEnv * env, char *mainClassName, int nameIsUTF, int java_argc, char **java_argv, HyPortLibrary * portLibrary)); @@ -129,8 +130,6 @@ int genericLauncher = 0; char *str; char *knownGenericNames[] = { "java", "java.exe", "javaw.exe", NULL }; - char *dirs[2]; - PORT_ACCESS_FROM_PORT (args->portLibrary); @@ -271,7 +270,7 @@ } /* Find the directory of the dll and set up the path */ - vmdllsubdir = vmdlldir_parseCmdLine (PORTLIB, argc - 1, argv); + vmdllsubdir = vmdlldir_parseCmdLine (argc - 1, argv); if (!vmdllsubdir) { vmdllsubdir = defaultDirName; } @@ -309,17 +308,6 @@ strcat (vmiPath, DIR_SEPERATOR_STRING); strcat (vmiPath, vmdll); - dirs[0] = newPathToAdd; - dirs[1] = exeName; - - rc = addDirsToPath(PORTLIB, 2, dirs, argv); - - if (rc == -1) - { - hytty_printf (PORTLIB, "addDirsToPath Failed\n"); - goto bail; - } - if (showVersion == 1) { if (!versionWritten) @@ -566,7 +554,7 @@ * if the argument cannot be found. */ char *VMCALL -vmdlldir_parseCmdLine (HyPortLibrary * portLibrary, UDATA lastLegalArg, +vmdlldir_parseCmdLine (UDATA lastLegalArg, char **argv) { UDATA i; @@ -1003,7 +991,7 @@ * */ static IDATA -addDirsToPath (HyPortLibrary * portLibrary, int count, char *newPathToAdd[], char **argv) +addDirsToPath (int count, char *newPathToAdd[], char **argv) { char *oldPath = NULL; char *variableName = NULL; @@ -1015,9 +1003,7 @@ int i=0; int strLen; - PORT_ACCESS_FROM_PORT (portLibrary); - - hysysinfo_get_executable_name (argv[0], &exeName); + main_get_executable_name (argv[0], &exeName); #if defined(WIN32) variableName = "PATH"; @@ -1066,7 +1052,7 @@ } } - newPath = hymem_allocate_memory(strLen + 1); + newPath = main_mem_allocate_memory(strLen + 1); strcpy (newPath, variableName); strcat (newPath, "="); @@ -1456,3 +1442,67 @@ return NULL; } + + +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, HY_PATH_SLASH); + 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; + + printf( "RON newPathToAdd: %s exeName: %s\n", newPathToAdd, 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; +} \ No newline at end of file Index: shared/main_hlp.h =================================================================== --- shared/main_hlp.h +++ shared/main_hlp.h @@ -0,0 +1,36 @@ +/* + * 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. + */ + +#if !defined(MAINHLP_H) +#define MAINHLP_H +#if defined(__cplusplus) +extern "C" +{ +#endif +#include "hycomp.h" + +extern HY_CFUNC int main_get_executable_name PROTOTYPE((char *argv0, char **exeName)); +extern HY_CFUNC void *main_mem_allocate_memory PROTOTYPE((int byteAmount)); +extern HY_CFUNC void main_mem_free_memory PROTOTYPE((void *memoryPointer)); +extern HY_CFUNC int main_open_port_library PROTOTYPE((UDATA * descriptor)); +extern HY_CFUNC int main_close_port_library PROTOTYPE((UDATA descriptor)); +extern HY_CFUNC UDATA main_lookup_name PROTOTYPE((UDATA descriptor, char *name, UDATA * func)); + +#if defined(__cplusplus) +} +#endif +#endif /* MAINHLP_H */ Index: unix/makefile =================================================================== --- unix/makefile (revision 501409) +++ unix/makefile (working copy) @@ -21,9 +21,8 @@ BUILDFILES = $(SHAREDSUB)main.o $(SHAREDSUB)cmain.o \ $(SHAREDSUB)launcher_copyright.o $(SHAREDSUB)strbuf.o \ - $(SHAREDSUB)libhlp.o -MDLLIBFILES = $(LIBPATH)libhycommon.a $(DLLPATH)libhyprt.so \ - $(DLLPATH)libhythr.so $(DLLPATH)libhysig.so + $(SHAREDSUB)libhlp.o main_hlp.o +MDLLIBFILES = $(LIBPATH)libhycommon.a $(DLLPATH)libhysig.so EXENAME = $(EXEPATH)java include $(HY_HDK)/build/make/rules.mk Index: unix/main_hlp.c =================================================================== --- unix/main_hlp.c +++ unix/main_hlp.c @@ -0,0 +1,405 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#if defined(LINUX) +#include +#endif +#if defined(FREEBSD) +#include +#include +#endif + +#include + +#include +#include +#include +#include + + +#include "main_hlp.h" + + +static BOOLEAN isSymbolicLink (char *filename); +static IDATA cwdname (char **result); +static IDATA readSymbolicLink (char *linkFilename, char **result); +static IDATA searchSystemPath (char *filename, char **result); + + +int +main_get_executable_name (char *argv0, char **result) +{ + +#if defined(LINUX) + return readSymbolicLink ("/proc/self/exe", result); +#else + IDATA retval = -1; + IDATA length; + char *p; + char *currentName = NULL; + char *currentPath = NULL; + char *originalWorkingDirectory = NULL; + + if (!argv0) + { + return -1; + } + currentPath = main_mem_allocate_memory(strlen (argv0) + 1); + if (currentPath) + { + strcpy(currentPath, argv0); + } + if (!currentPath) + { + retval = -1; + goto cleanup; + } + retval = cwdname(&originalWorkingDirectory); + if (retval) + { + retval = -1; + goto cleanup; + } +gotPathName: + /* split path into directory part and filename part. */ + p = strrchr (currentPath, '/'); + if (p) + { + *p++ = '\0'; + currentName = main_mem_allocate_memory(strlen (p) + 1); + if (!currentName) + { + retval = -1; + goto cleanup; + } + strcpy (currentName, p); + } + else + { + currentName = currentPath; + currentPath = NULL; + retval = searchSystemPath (currentName, ¤tPath); + if (retval) + { + retval = -1; + goto cleanup; + } + } + /* go there */ + if (currentPath) + { + if (currentPath[0]) + { + if (0 != chdir (currentPath)) + { + retval = -1; + goto cleanup; + } + } + main_mem_free_memory(currentPath); + currentPath = NULL; + } + if (isSymbolicLink (currentName)) + { + /* try to follow the link. */ + retval = readSymbolicLink (currentName, ¤tPath); + if (retval) + { + retval = -1; + goto cleanup; + } + main_mem_free_memory(currentName); + currentName = NULL; + goto gotPathName; + } + retval = cwdname (¤tPath); + if (retval) + { + retval = -1; + goto cleanup; + } + /* Put name and path back together */ + *result = main_mem_allocate_memory(strlen(currentPath) + strlen(currentName) + 2); + if (!*result) + { + retval = -1; + goto cleanup; + } + strcpy (*result, currentPath); + if (currentPath[0] && (currentPath[strlen (currentPath) - 1] != '/')) + { + strcat (*result, "/"); + } + strcat (*result, currentName); + /* Finished. */ + retval = 0; +cleanup: + if (originalWorkingDirectory) + { + chdir (originalWorkingDirectory); + main_mem_free_memory(originalWorkingDirectory); + originalWorkingDirectory = NULL; + } + if (currentPath) + { + main_mem_free_memory(currentPath); + currentPath = NULL; + } + if (currentName) + { + main_mem_free_memory(currentName); + currentName = NULL; + } + return retval; +#endif +} + +void * +main_mem_allocate_memory (int byteAmount) +{ + void *pointer = NULL; + void *mem; + if (byteAmount == 0) + { /* prevent malloc from failing causing allocate to return null */ + byteAmount = 1; + } + pointer = malloc(byteAmount); + return pointer; +} + +void +main_mem_free_memory (void *memoryPointer) +{ + free (memoryPointer); +} + + +/** + * @internal Examines the named file to determine if it is a symbolic link. On platforms which don't have + * symbolic links (or where we can't tell) or if an unexpected error occurs, just answer FALSE. + */ +static BOOLEAN +isSymbolicLink (char *filename) +{ + struct stat statbuf; + if (!lstat (filename, &statbuf)) + { + if (S_ISLNK (statbuf.st_mode)) + { + return TRUE; + } + } + return FALSE; +} + +/** + * @internal Returns the current working directory. + * + * @return 0 on success, -1 on failure. + * + * @note The buffer to hold this string (including its terminating NUL) is allocated with + * main_mem_allocate_memory. The caller should free this memory with + * main_mem_free_memory when it is no longer needed. + */ +static IDATA +cwdname (char **result) +{ + char *cwd; + int allocSize = 256; + +doAlloc: + cwd = main_mem_allocate_memory(allocSize); + if (!cwd) + { + return -1; + } + if (!getcwd (cwd, allocSize - 1)) + { + main_mem_free_memory(cwd); + if (errno == ERANGE) + { + allocSize += 256; + goto doAlloc; + } + return -1; + } + *result = cwd; + return 0; +} + + +/** + * @internal Attempts to read the contents of a symbolic link. (The contents are the relative pathname of + * the thing linked to). A buffer large enough to hold the result (and the terminating NUL) is + * allocated with main_mem_allocate_memory. The caller should free this buffer with + * main_mem_free_memory when it is no longer needed. + * On success, returns 0. On error, returns -1. + */ +static IDATA +readSymbolicLink (char *linkFilename, + char **result) +{ + /* TODO: remove this ifdef and find out what other builds break (if any) */ +#if defined(LINUX) + char fixedBuffer[PATH_MAX + 1]; + int size = readlink (linkFilename, fixedBuffer, sizeof (fixedBuffer) - 1); + if (size <= 0) + { + return -1; + } + fixedBuffer[size++] = '\0'; + *result = main_mem_allocate_memory(size); + if (!*result) + { + return -1; + } + strcpy (*result, fixedBuffer); + return 0; +#else + return -1; +#endif +} + + +/** + * @internal Searches through the system PATH for the named file. If found, it returns the path entry + * which matched the file. A buffer large enough to hold the proper path entry (without a + * trailing slash, but with the terminating NUL) is allocated with main_mem_allocate_memory. + * The caller should free this buffer with main_mem_free_memory when it is no longer + * needed. On success, returns 0. On error (including if the file is not found), -1 is returned. + */ +static IDATA +searchSystemPath (char *filename, char **result) +{ + char *pathCurrent; + char *pathNext; + int length; + DIR *sdir = NULL; + struct dirent *dirEntry; + /* This should be sufficient for a single entry in the PATH var, though the var itself */ + /* could be considerably longer.. */ + char temp[PATH_MAX + 1]; + + if (!(pathNext = getenv ("PATH"))) + { + return -1; + } + + while (pathNext) + { + pathCurrent = pathNext; + pathNext = strchr (pathCurrent, ':'); + if (pathNext) + { + length = (pathNext - pathCurrent); + pathNext += 1; + } + else + { + length = strlen (pathCurrent); + } + if (length > PATH_MAX) + { + length = PATH_MAX; + } + memcpy (temp, pathCurrent, length); + temp[length] = '\0'; + + if (!length) + { /* empty path entry */ + continue; + } + if (sdir = opendir (temp)) + { + while (dirEntry = readdir (sdir)) + { + if (!strcmp (dirEntry->d_name, filename)) + { + closedir (sdir); + /* found! */ + *result = main_mem_allocate_memory(strlen (temp) + 1); + if (!result) + { + return -1; + } + strcpy (*result, temp); + return 0; + } + } + closedir (sdir); + } + } + /* not found */ + return -1; +} + +/** + * Close a shared library. + * + * @param[in] descriptor Shared library handle to close. + * + * @return 0 on success, any other value on failure. + */ +UDATA VMCALL +main_close_port_library (UDATA descriptor) +{ + return (UDATA) dlclose ((void *)descriptor); +} + +/** + * Opens a shared library . + * + * @param[out] descriptor Pointer to memory which is filled in with shared-library handle on success. + * + * @return 0 on success, any other value on failure. + * + * @note contents of descriptor are undefined on failure. + */ +UDATA VMCALL +main_open_port_library (UDATA * descriptor) +{ + void *handle; + char *openName = "libhyprt.so"; + + handle = dlopen (openName, RTLD_NOW); + if (handle == NULL) + { + return -1; + } + + *descriptor = (UDATA) handle; + return 0; +} + + +/** + * Search for a function named 'name' taking argCount in the shared library 'descriptor'. + * + * @param[in] descriptor Shared library to search. + * @param[in] name Function to look up. + * @param[out] func Pointer to the function. + * + * @return 0 on success, any other value on failure. + * + * @note contents of func are undefined on failure. + */ +UDATA VMCALL +main_lookup_name (UDATA descriptor, char *name, UDATA * func) +{ + void *address; + address = dlsym ((void *)descriptor, name); + if (address == NULL) + { + return 1; + } + *func = (UDATA) address; + return 0; +} \ No newline at end of file Index: windows/makefile.javae =================================================================== --- windows/makefile.javae (revision 501409) +++ windows/makefile.javae (working copy) @@ -23,9 +23,10 @@ HYCFLAGS = $(HYCFLAGS) /I$(SHAREDSUB) BUILDFILES = $(SHAREDSUB)launcher_copyright.obj $(SHAREDSUB)cmain.obj \ - $(SHAREDSUB)main.obj $(SHAREDSUB)strbuf.obj $(SHAREDSUB)libhlp.obj + $(SHAREDSUB)main.obj $(SHAREDSUB)strbuf.obj $(SHAREDSUB)libhlp.obj \ + main_hlp.obj VIRTFILES = java.res -MDLLIBFILES = $(LIBPATH)hycommon.lib $(LIBPATH)hyprt.lib $(LIBPATH)hythr.lib +MDLLIBFILES = $(LIBPATH)hycommon.lib EXEFLAGS=$(conlflags) -subsystem:console EXEDLLFILES=$(conlibsdll) Index: windows/makefile.javaw =================================================================== --- windows/makefile.javaw (revision 501409) +++ windows/makefile.javaw (working copy) @@ -20,10 +20,13 @@ !include <$(HY_HDK)\build\make\defines.mak> EXENAME=$(EXEPATH)javaw.exe +HYCFLAGS = $(HYCFLAGS) /I$(SHAREDSUB) + BUILDFILES = $(SHAREDSUB)launcher_copyright.obj $(SHAREDSUB)main.obj \ - winmain.obj $(SHAREDSUB)strbuf.obj $(SHAREDSUB)libhlp.obj + winmain.obj $(SHAREDSUB)strbuf.obj $(SHAREDSUB)libhlp.obj \ + main_hlp.obj VIRTFILES = javaw.res -MDLLIBFILES = $(LIBPATH)hycommon.lib $(LIBPATH)hyprt.lib $(LIBPATH)hythr.lib +MDLLIBFILES = $(LIBPATH)hycommon.lib EXEFLAGS=$(guilflags) -subsystem:windows EXEDLLFILES=$(guilibsdll) Index: windows/winmain.c =================================================================== --- windows/winmain.c (revision 501409) +++ windows/winmain.c (working copy) @@ -19,16 +19,18 @@ #include "jni.h" #include "hyport.h" //#include "libhlp.h" +#include "main_hlp.h" /* external prototypes */ UDATA VMCALL gpProtectedMain PROTOTYPE ((void *arg)); +extern int main_addVMDirToPath PROTOTYPE((int argc, char **argv, char **envp)); char **getArgvCmdLine -PROTOTYPE ((HyPortLibrary * portLibrary, LPTSTR buffer, int *finalArgc)); +PROTOTYPE ((LPTSTR buffer, int *finalArgc)); int WINAPI WinMain PROTOTYPE ((HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)); -void freeArgvCmdLine PROTOTYPE ((HyPortLibrary * portLibrary, char **argv)); +void freeArgvCmdLine PROTOTYPE ((char **argv)); struct haCmdlineOptions { @@ -38,6 +40,11 @@ HyPortLibrary *portLibrary; }; +typedef I_32 (PVMCALL hyport_init_library_type) (struct HyPortLibrary *portLibrary, + struct HyPortLibraryVersion *version, + UDATA size); + + int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) @@ -47,6 +54,32 @@ HyPortLibraryVersion portLibraryVersion; struct haCmdlineOptions options; char **argv; + UDATA portLibDescriptor; + hyport_init_library_type port_init_library_func; + + argv = getArgvCmdLine (GetCommandLine (), &argc); + if (argv == NULL) { + rc = -1; + goto cleanup; + } + + /* determine which VM directory to use and add it to the path */ + rc = main_addVMDirToPath(argc, argv, NULL); + if ( rc != 0 ) { + goto cleanup; + } + + if ( 0 != main_open_port_library(&portLibDescriptor) ) { + fprintf( stderr, "failed to open hyprt library.\n" ); + rc = -1; + goto cleanup; + } + + if ( 0 != main_lookup_name( portLibDescriptor, "hyport_init_library", (UDATA *)&port_init_library_func) ) { + fprintf( stderr, "failed to find hyport_init_library function in hyprt library\n" ); + rc = -1; + goto cleanup; + } /* Use portlibrary version which we compiled against, and have allocated space * for on the stack. This version may be different from the one in the linked DLL. @@ -53,31 +86,23 @@ */ HYPORT_SET_VERSION (&portLibraryVersion, HYPORT_CAPABILITY_MASK); - rc = - hyport_init_library (&hyportLibrary, &portLibraryVersion, - sizeof (HyPortLibrary)); - if (0 != rc) - { - return -1; - } + rc = port_init_library_func (&hyportLibrary, &portLibraryVersion, sizeof (HyPortLibrary)); + if (0 != rc) { + goto cleanup; + } + + options.argc = argc; + options.argv = argv; + options.envp = NULL; + options.portLibrary = &hyportLibrary; + rc = hyportLibrary.gp_protect (&hyportLibrary, gpProtectedMain, &options); + hyportLibrary.port_shutdown_library (&hyportLibrary); - argv = getArgvCmdLine (&hyportLibrary, GetCommandLine (), &argc); - if (argv) - { - options.argc = argc; - options.argv = argv; - options.envp = NULL; - options.portLibrary = &hyportLibrary; - rc = - hyportLibrary.gp_protect (&hyportLibrary, gpProtectedMain, &options); - freeArgvCmdLine (&hyportLibrary, argv); - hyportLibrary.port_shutdown_library (&hyportLibrary); - return rc; - } - else - { - return -1; - } +cleanup: + if (argv) { + freeArgvCmdLine(argv); + } + return rc; } /* @@ -87,7 +112,7 @@ * also converts the string to ASCII. */ char ** -getArgvCmdLine (HyPortLibrary * portLibrary, LPTSTR buffer, int *finalArgc) +getArgvCmdLine (LPTSTR buffer, int *finalArgc) { #define QUOTE_CHAR 34 @@ -95,7 +120,6 @@ int argc = 0, currentArg, i, asciiLen; char *asciiCmdLine; char **argv; - PORT_ACCESS_FROM_PORT (portLibrary); asciiCmdLine = buffer; @@ -109,7 +133,7 @@ } /* allocate the buffer for the args */ - argv = hymem_allocate_memory (argc * sizeof (char *)); + argv = main_mem_allocate_memory (argc * sizeof (char *)); if (!argv) return NULL; @@ -168,9 +192,7 @@ #undef QUOTE_CHAR void -freeArgvCmdLine (HyPortLibrary * portLibrary, char **argv) +freeArgvCmdLine (char **argv) { - PORT_ACCESS_FROM_PORT (portLibrary); - - hymem_free_memory (argv); + main_mem_free_memory (argv); } Index: windows/main_hlp.c =================================================================== --- windows/main_hlp.c +++ windows/main_hlp.c @@ -0,0 +1,171 @@ +#include +#include +#include +#include + +#include "main_hlp.h" + +int +main_get_executable_name (char *argv0, char **result) +{ + char *temp; + TCHAR osTemp[_MAX_PATH + 2]; + DWORD length; + + (void) argv0; /* unused */ + + length = GetModuleFileName (NULL, osTemp, _MAX_PATH + 1); + if (!length || (length >= _MAX_PATH)) + { + return -1; + } + osTemp[length] = (TCHAR) '\0'; /* jic */ + +#if defined(UNICODE) + length = + WideCharToMultiByte (CP_ACP, WC_COMPOSITECHECK, osTemp, -1, NULL, 0, NULL, + NULL); + temp = main_mem_allocate_memory (length + 1); + if (!temp) + { + return -1; + } + length = + WideCharToMultiByte (CP_ACP, WC_COMPOSITECHECK, osTemp, -1, temp, length, + NULL, NULL); +#else + temp = main_mem_allocate_memory (length + 1); + if (!temp) + { + return -1; + } + strcpy (temp, osTemp); +#endif + +*result = temp; +return 0; +} + +void * +main_mem_allocate_memory(int byteAmount) +{ + void *pointer = NULL; + if (byteAmount == 0) + { /* prevent GlobalLock from failing causing allocate to return null */ + byteAmount = 1; + } + pointer = HeapAlloc (GetProcessHeap(), 0, byteAmount); + return pointer; +} + +void +main_mem_free_memory(void *memoryPointer) +{ + HeapFree (GetProcessHeap(), 0, memoryPointer); +} + +#if !defined(HINSTANCE_ERROR) +#define HINSTANCE_ERROR 32 +#endif + +static UDATA +EsSharedLibraryLookupName (UDATA descriptor, char *name, UDATA * func) +{ + UDATA lpfnFunction; + + if (descriptor < HINSTANCE_ERROR) + { + return 3; + } + lpfnFunction = + (UDATA) GetProcAddress ((HINSTANCE) descriptor, (LPCSTR) name); + if (lpfnFunction == (UDATA) NULL) + { + return 4; + } + *func = lpfnFunction; + return 0; +} + +/** + * Opens the port library. + * + * @param[out] descriptor Pointer to memory which is filled in with shared-library handle on success. + * + * @return 0 on success, any other value on failure. + * + * @note contents of descriptor are undefined on failure. + */ +int +main_open_port_library (UDATA * descriptor) +{ + HINSTANCE dllHandle; + UINT prevMode; + + prevMode = SetErrorMode (SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS); + + /* LoadLibrary will try appending .DLL if necessary */ + dllHandle = LoadLibrary ("hyprt"); + if (dllHandle >= (HINSTANCE) HINSTANCE_ERROR) + { + *descriptor = (UDATA) dllHandle; + SetErrorMode (prevMode); + return 0; + } + return -1; +} + +/** + * Close the port library. + * + * @param[in] descriptor Shared library handle to close. + * + * @return 0 on success, any other value on failure. + */ +int +main_close_port_library (UDATA descriptor) +{ + if (descriptor < HINSTANCE_ERROR) + { + return 2; + } + FreeLibrary ((HINSTANCE) descriptor); + return 0; +} + +/** + * Search for a function named 'name' taking argCount in the shared library 'descriptor'. + * + * @param[in] descriptor Shared library to search. + * @param[in] name Function to look up. + * @param[out] func Pointer to the function. + * + * @return 0 on success, any other value on failure. + * + * argSignature is a C (ie: NUL-terminated) string with the following possible values for each character: + * + * V - void + * Z - boolean + * B - byte + * C - char (16 bits) + * I - integer (32 bits) + * J - long (64 bits) + * F - float (32 bits) + * D - double (64 bits) + * L - object / pointer (32 or 64, depending on platform) + * P - pointer-width platform data. (in this context an IDATA) + * + * Lower case signature characters imply unsigned value. + * Upper case signature characters imply signed values. + * If it doesn't make sense to be signed/unsigned (eg: V, L, F, D Z) the character is upper case. + * + * argList[0] is the return type from the function. + * The argument list is as it appears in english: list is left (1) to right (argCount) + * + * @note contents of func are undefined on failure. + */ +UDATA +main_lookup_name (UDATA descriptor, char *name, UDATA * func) +{ + return EsSharedLibraryLookupName (descriptor, name, func); +} \ No newline at end of file