| /* |
| * Copyright (c) 2000, 2018 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Andre Weinand (OTI Labs) |
| * David Green - OpenJDK bsd port integration |
| * Rapicorp, Inc - Default the configuration to Application Support (bug 461725) |
| * Mikael Barbero - Rename *Carbon* files to *Cocoa* (bug 383545) |
| * Christian Georgi (SAP SE) - Fix VM path for new file layout (bug 469766) |
| */ |
| |
| /* MacOS X Cocoa specific logic for displaying the splash screen. */ |
| |
| #include "eclipseOS.h" |
| #include "eclipseCommon.h" |
| #include "eclipseJNI.h" |
| #include "eclipseUtil.h" |
| |
| #include <sys/xattr.h> |
| #include <string.h> |
| #include <unistd.h> |
| #include <sys/stat.h> |
| #include <CoreServices/CoreServices.h> |
| #include <Cocoa/Cocoa.h> |
| #include <mach-o/dyld.h> |
| |
| #define startupJarName "startup.jar" |
| #define LAUNCHER "-launcher" |
| #define SPLASH_LAUNCHER "/Resources/Splash.app/Contents/" |
| |
| #define DEBUG 0 |
| |
| static _TCHAR* noForkingMsg = _T_ECLIPSE("Internal Error, forking the jvm is not supported on MacOS.\n"); |
| static const _TCHAR* INSTALL_UUID = _T_ECLIPSE("eclipse.uuid"); |
| |
| char *findCommand(char *command); |
| |
| /* Global Variables */ |
| char* defaultVM = "java"; |
| char* vmLibrary = "JavaVM"; |
| char* shippedVMDir = "../../jre/Contents/Home/bin/"; // relative to launcher |
| int isModularJVM = 0; |
| |
| static void adjustLibraryPath(char * vmLibrary); |
| static char * findLib(char * command); |
| |
| #ifdef i386 |
| #define JAVA_ARCH "i386" |
| #define JAVA_HOME_ARCH "i386" |
| #elif defined(__amd64__) || defined(__x86_64__) |
| #define JAVA_ARCH "amd64" |
| #define JAVA_HOME_ARCH "x86_64" |
| #else |
| #define JAVA_ARCH DEFAULT_OS_ARCH |
| #define JAVA_HOME_ARCH DEFAULT_OS_ARCH |
| #endif |
| |
| #define LIB_PATH_VAR _T_ECLIPSE("LD_LIBRARY_PATH") |
| #define DYLD_FALLBACK_VAR _T_ECLIPSE("DYLD_FALLBACK_LIBRARY_PATH") |
| |
| #define MAX_LOCATION_LENGTH 40 /* none of the jvmLocations strings should be longer than this */ |
| #define MAX_JVMLIB_LENGTH 15 /* none of the jvmLibs strings should be longer than this */ |
| static const char* jvmLocations[] = { |
| "../lib/" JAVA_ARCH "/client", |
| "../lib/" JAVA_ARCH "/server", |
| "../lib/client", |
| "../lib/server", |
| "../jre/lib/" JAVA_ARCH "/client", |
| "../jre/lib/" JAVA_ARCH "/server", |
| "../jre/lib/client", |
| "../jre/lib/server", |
| NULL |
| }; |
| static const char* jvmLibs[] = { "libjvm.dylib", "libjvm.jnilib", "libjvm.so", NULL }; |
| |
| /* Define the window system arguments for the various Java VMs. */ |
| static char* argVM_JAVA[] = { "-XstartOnFirstThread", NULL }; |
| |
| static NSWindow* window = nil; |
| @interface KeyWindow : NSWindow { } |
| - (BOOL)canBecomeKeyWindow; |
| @end |
| |
| @implementation KeyWindow |
| - (BOOL)canBecomeKeyWindow { |
| return YES; |
| } |
| |
| - (void)close { |
| [super close]; |
| window = nil; |
| } |
| |
| + (int)show: (NSString *) featureImage { |
| [[NSApplication sharedApplication] setActivationPolicy: NSApplicationActivationPolicyRegular]; |
| [[NSRunningApplication currentApplication] activateWithOptions: NSApplicationActivateIgnoringOtherApps]; |
| if (window != NULL) |
| return 0; /*already showing */ |
| if (featureImage == NULL) |
| return ENOENT; |
| |
| int result = ENOENT; |
| NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; |
| [NSApplication sharedApplication]; |
| NSImage* image = [[NSImage alloc] initByReferencingFile: featureImage]; |
| [featureImage release]; |
| if (image != NULL) { |
| NSImageRep* imageRep = [image bestRepresentationForDevice: [[NSScreen mainScreen] deviceDescription]]; |
| NSRect rect = {{0, 0}, {[imageRep pixelsWide], [imageRep pixelsHigh]}}; |
| [image setSize: NSMakeSize([imageRep pixelsWide], [imageRep pixelsHigh])]; |
| [image autorelease]; |
| window = [[KeyWindow alloc] initWithContentRect: rect styleMask: NSBorderlessWindowMask backing: NSBackingStoreBuffered defer: 0]; |
| if (window != nil) { |
| [window center]; |
| [window setBackgroundColor: [NSColor colorWithPatternImage: image]]; |
| [window makeKeyAndOrderFront: nil]; |
| dispatchMessages(); |
| result = 0; |
| } |
| } |
| [pool release]; |
| return result; |
| } |
| |
| + (void)shutdown { |
| if (window != 0) { |
| NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; |
| [window close]; |
| window = nil; |
| [pool release]; |
| } |
| } |
| |
| + (void)dispatch { |
| NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; |
| NSEvent* event; |
| NSApplication* application = [NSApplication sharedApplication]; |
| while ((event = [application nextEventMatchingMask: NSAnyEventMask untilDate: nil inMode: NSDefaultRunLoopMode dequeue: TRUE]) != nil) { |
| [application sendEvent: event]; |
| } |
| [pool release]; |
| } |
| |
| @end |
| |
| @interface AppleEventDelegate : NSObject |
| - (void)handleOpenDocuments:(NSAppleEventDescriptor *)event withReplyEvent: (NSAppleEventDescriptor *)replyEvent; |
| - (void)handleGetURL:(NSAppleEventDescriptor *)event withReplyEvent: (NSAppleEventDescriptor *)replyEvent; |
| @end |
| @implementation AppleEventDelegate |
| NSTimer *timerOpenDocuments; |
| NSMutableArray *files; |
| NSTimer *timerOpenUrls; |
| NSMutableArray *urls; |
| |
| - (void)handleOpenDocuments:(NSAppleEventDescriptor *)event withReplyEvent: (NSAppleEventDescriptor *)replyEvent { |
| NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; |
| int count = [event numberOfItems]; |
| int index = 1; |
| |
| if (!files) { |
| files = [NSMutableArray arrayWithCapacity:count]; |
| [files retain]; |
| } |
| |
| for (index = 1; index<=count; index++) { |
| CFURLRef url = NULL; |
| NSAppleEventDescriptor *desc = [event descriptorAtIndex:index], *coerceDesc; |
| if (!desc) continue; |
| if ((coerceDesc = [desc coerceToDescriptorType: typeFSRef]) != NULL) { |
| url = CFURLCreateFromFSRef(kCFAllocatorDefault, [[coerceDesc data] bytes]); |
| } else if ((coerceDesc = [desc coerceToDescriptorType: typeFileURL]) != NULL) { |
| NSData *data = [coerceDesc data]; |
| url = CFURLCreateWithBytes(kCFAllocatorDefault, [data bytes], [data length], kCFStringEncodingUTF8, NULL); |
| } |
| if (url) { |
| NSString *pathName = (NSString *)CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle); |
| [files addObject:pathName]; |
| [pathName release]; |
| CFRelease(url); |
| } |
| } |
| |
| if (!timerOpenDocuments) { |
| timerOpenDocuments = [NSTimer scheduledTimerWithTimeInterval: 1.0 |
| target: self |
| selector: @selector(handleOpenDocumentsTimer:) |
| userInfo: nil |
| repeats: YES]; |
| } |
| [pool release]; |
| } |
| |
| - (void) handleOpenDocumentsTimer: (NSTimer *) timer { |
| NSObject *delegate = [[NSApplication sharedApplication] delegate]; |
| if (delegate != NULL && [delegate respondsToSelector: @selector(application:openFiles:)]) { |
| [delegate performSelector:@selector(application:openFiles:) withObject:[NSApplication sharedApplication] withObject:files]; |
| [files release]; |
| files = NULL; |
| [timerOpenDocuments invalidate]; |
| } |
| } |
| |
| - (void)handleGetURL:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent { |
| NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; |
| |
| NSString *url = [[event paramDescriptorForKeyword:keyDirectObject] stringValue]; |
| |
| NSObject *delegate = [[NSApplication sharedApplication] delegate]; |
| if (delegate != NULL && [delegate respondsToSelector: @selector(application:openUrls:)]) { |
| [delegate performSelector:@selector(application:openUrls:) withObject:[NSApplication sharedApplication] withObject:[NSArray arrayWithObject:url]]; |
| } else { |
| if (!urls) { |
| urls = [NSMutableArray arrayWithCapacity:1]; |
| [urls retain]; |
| } |
| |
| [urls addObject:url]; |
| |
| if (!timerOpenUrls) { |
| timerOpenUrls = [NSTimer scheduledTimerWithTimeInterval: 1.0 |
| target: self |
| selector: @selector(handleOpenUrlsTimer:) |
| userInfo: nil |
| repeats: YES]; |
| } |
| } |
| |
| [pool release]; |
| } |
| |
| - (void) handleOpenUrlsTimer: (NSTimer *) timer { |
| NSObject *delegate = [[NSApplication sharedApplication] delegate]; |
| if (delegate != NULL && [delegate respondsToSelector: @selector(application:openUrls:)]) { |
| [delegate performSelector:@selector(application:openUrls:) withObject:[NSApplication sharedApplication] withObject:urls]; |
| [urls release]; |
| urls = NULL; |
| [timerOpenUrls invalidate]; |
| timerOpenUrls = NULL; |
| } |
| } |
| @end |
| |
| int main() { |
| return -1; |
| } |
| |
| void installAppleEventHandler(); |
| |
| int reuseWorkbench(_TCHAR** filePath, int timeout) { |
| installAppleEventHandler(); |
| return 0; |
| } |
| |
| /* Show the Splash Window |
| * |
| * Create the splash window, load the bitmap and display the splash window. |
| */ |
| int showSplash( const _TCHAR* featureImage ) |
| { |
| int result = 0; |
| NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; |
| NSString *str = [[NSString stringWithUTF8String: featureImage] retain]; |
| if ([NSThread isMainThread]) { |
| result = [KeyWindow show: str]; |
| } else { |
| [KeyWindow performSelectorOnMainThread: @selector(show:) withObject: str waitUntilDone: 0]; |
| } |
| [pool release]; |
| return result; |
| } |
| |
| void takeDownSplash() { |
| NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; |
| if ([NSThread isMainThread]) { |
| [KeyWindow shutdown]; |
| } else { |
| [KeyWindow performSelectorOnMainThread: @selector(shutdown) withObject: nil waitUntilDone: 0]; |
| } |
| [pool release]; |
| } |
| |
| void dispatchMessages() { |
| NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; |
| if ([NSThread isMainThread]) { |
| [KeyWindow dispatch]; |
| } else { |
| [KeyWindow performSelectorOnMainThread: @selector(dispatch) withObject: nil waitUntilDone: 0]; |
| } |
| [pool release]; |
| } |
| |
| void installAppleEventHandler() { |
| NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; |
| AppleEventDelegate *appleEventDelegate = [[AppleEventDelegate alloc] init]; |
| [NSApplication sharedApplication]; |
| NSAppleEventManager *manager = [NSAppleEventManager sharedAppleEventManager]; |
| [manager setEventHandler:appleEventDelegate |
| andSelector:@selector(handleOpenDocuments:withReplyEvent:) |
| forEventClass:kCoreEventClass |
| andEventID:kAEOpenDocuments]; |
| [manager setEventHandler:appleEventDelegate |
| andSelector:@selector(handleGetURL:withReplyEvent:) |
| forEventClass:kInternetEventClass |
| andEventID:kAEGetURL]; |
| // [appleEventDelegate release]; |
| [pool release]; |
| } |
| |
| jlong getSplashHandle() { |
| return (jlong)window; |
| } |
| |
| /* Get the window system specific VM arguments */ |
| char** getArgVM( char* vm ) |
| { |
| char** result; |
| |
| /* Use the default arguments for a standard Java VM */ |
| result = argVM_JAVA; |
| |
| return result; |
| } |
| |
| /* set isModularJVM to 1 if the JVM version is >= 9, 0 otherwise */ |
| void checkJavaVersion(char* command) { |
| FILE *fp; |
| char buffer[4096]; |
| char *version = NULL, *firstChar; |
| int numChars = 0; |
| sprintf(buffer,"%s -version 2>&1", command); |
| fp = popen(buffer, "r"); |
| if (fp == NULL) { |
| return; |
| } |
| while (fgets(buffer, sizeof(buffer)-1, fp) != NULL) { |
| if (!version) { |
| firstChar = (char *) (strchr(buffer, '"') + 1); |
| if (firstChar != NULL) |
| numChars = (int) (strrchr(buffer, '"') - firstChar); |
| |
| /* Allocate a buffer and copy the version string into it. */ |
| if (numChars > 0) |
| { |
| version = malloc( numChars + 1 ); |
| strncpy(version, firstChar, numChars); |
| version[numChars] = '\0'; |
| } |
| } |
| if (version != NULL) { |
| char *str = version; |
| /* According to the new Java version-string scheme, the first element is |
| * the major version number, details at http://openjdk.java.net/jeps/223 */ |
| char *majorVersion = strtok(str, ".-"); |
| if (majorVersion != NULL && (strtol(majorVersion, NULL, 10) >= 9)) { |
| isModularJVM = 1; |
| } |
| free(version); |
| } |
| break; |
| } |
| pclose(fp); |
| return; |
| } |
| |
| char * getJavaHome() { |
| FILE *fp; |
| char path[4096]; |
| char *result, *start; |
| sprintf(path, "/usr/libexec/java_home -a %s", JAVA_HOME_ARCH); |
| fp = popen(path, "r"); |
| if (fp == NULL) { |
| return NULL; |
| } |
| path[0] = 0; |
| while (fgets(path, sizeof(path)-1, fp) != NULL) { |
| } |
| if(path[0]==0) { |
| return NULL; |
| } |
| result = path; |
| start = strchr(result, '\n'); |
| if (start) { |
| start[0] = 0; |
| } |
| sprintf(path, "%s/bin/java", result); |
| pclose(fp); |
| return strdup(path); |
| } |
| |
| char * findVMLibrary( char* command ) { |
| char *start, *end; |
| char *version, *result, *cmd; |
| int length; |
| |
| /*check first to see if command already points to the library */ |
| if (strcmp(command, JAVA_FRAMEWORK) == 0) { |
| return JAVA_FRAMEWORK; |
| } |
| |
| /* select a version to use based on the command */ |
| start = strstr(command, "/Versions/"); |
| if (start != NULL){ |
| start += 10; |
| end = strchr( start, dirSeparator); |
| if (end != NULL && end > start) { |
| length = end - start; |
| version = malloc(length + 1); |
| strncpy(version, start, length); |
| version[length] = 0; |
| |
| /*only set a version if it starts with a number */ |
| if(strtol(version, NULL, 10) != 0 || version[0] == '0') { |
| setenv("JAVA_JVM_VERSION", version, 1); |
| } |
| |
| free(version); |
| } |
| } |
| cmd = command; |
| if ((strstr(cmd, "/JavaVM.framework/") != NULL && (strstr(cmd, "/Current/") != NULL)) || strstr(cmd, "/A/") != NULL || strstr(cmd, "/usr/bin/java") != NULL ) { |
| //On Mac we have universal library at /usr/bin/java. But actual java is some where else. So if the path received is default path we need look for java home |
| cmd = getJavaHome(); |
| if (cmd == NULL) { |
| return NULL; |
| } |
| } |
| // This is necessary to initialize isModularJVM |
| checkJavaVersion(cmd); |
| result = JAVA_FRAMEWORK; |
| if (strstr(cmd, "/JavaVM.framework/") == NULL) { |
| char * lib = findLib(cmd); |
| if (lib != NULL) { |
| // This does not seem to be necessary to load the Mac JVM library |
| if (0) adjustLibraryPath(lib); |
| result = lib; |
| } |
| } |
| if (cmd != command) free(cmd); |
| return result; |
| } |
| |
| static char * findLib(char * command) { |
| int i, q; |
| int pathLength; |
| struct stat stats; |
| char * path; /* path to resulting jvm shared library */ |
| char * location; /* points to begining of jvmLocations section of path */ |
| |
| if (command != NULL) { |
| /*check first to see if command already points to the library */ |
| if (isVMLibrary(command)) { |
| if (stat(command, &stats) == 0 && (stats.st_mode & S_IFREG) != 0) { /* found it */ |
| return strdup(command); |
| } |
| return NULL; |
| } |
| |
| location = strrchr(command, dirSeparator) + 1; |
| pathLength = location - command; |
| path = malloc((pathLength + MAX_LOCATION_LENGTH + 1 + MAX_JVMLIB_LENGTH + 1) * sizeof(char)); |
| strncpy(path, command, pathLength); |
| location = &path[pathLength]; |
| |
| /* |
| * We are trying base/jvmLocations[*]/vmLibrary |
| * where base is the directory containing the given java command, normally jre/bin |
| */ |
| for (q = 0; jvmLibs[q] != NULL; ++q) { |
| const char *jvmLib = jvmLibs[q]; |
| i = -1; |
| while (jvmLocations[++i] != NULL) { |
| sprintf(location, "%s%c%s", jvmLocations[i], dirSeparator, jvmLib); |
| /*fprintf(stderr,"checking path: %s\n",path);*/ |
| if (stat(path, &stats) == 0 && (stats.st_mode & S_IFREG) != 0) |
| { /* found it */ |
| return path; |
| } |
| } |
| } |
| } |
| return NULL; |
| } |
| |
| /* adjust the LD_LIBRARY_PATH for the vmLibrary */ |
| static void adjustLibraryPath(char * vmLibrary) { |
| char * c; |
| char * ldPath, *dylibPath; |
| char * newPath; |
| int i; |
| int numPaths = 0; |
| int length = 0; |
| int needAdjust = 0, needDylibAdjust = 0; |
| |
| char ** paths = getVMLibrarySearchPath(vmLibrary); |
| |
| ldPath = (char*) getenv(LIB_PATH_VAR); |
| if (!ldPath) { |
| ldPath = _T_ECLIPSE(""); |
| needAdjust = 1; |
| } else { |
| needAdjust = !containsPaths(ldPath, paths); |
| } |
| |
| dylibPath = (char*) getenv(DYLD_FALLBACK_VAR); |
| if (!dylibPath) { |
| dylibPath = _T_ECLIPSE(""); |
| needDylibAdjust = 1; |
| } else { |
| needDylibAdjust = !containsPaths(dylibPath, paths); |
| } |
| |
| if (!needAdjust && !needDylibAdjust) { |
| for (i = 0; paths[i] != NULL; i++) |
| free(paths[i]); |
| free(paths); |
| return; |
| } |
| |
| c = concatStrings(paths); |
| |
| /* set the value for LD_LIBRARY_PATH */ |
| length = strlen(ldPath); |
| newPath = malloc((_tcslen(c) + length + 1) * sizeof(_TCHAR)); |
| _stprintf(newPath, _T_ECLIPSE("%s%s"), c, ldPath); |
| setenv(LIB_PATH_VAR, newPath, 1); |
| free(newPath); |
| |
| /* set the value for DYLD_FALLBACK_LIBRARY_PATH */ |
| length = strlen(dylibPath); |
| newPath = malloc((_tcslen(c) + length + 1) * sizeof(_TCHAR)); |
| _stprintf(newPath, _T_ECLIPSE("%s%s"), c, dylibPath); |
| setenv(DYLD_FALLBACK_VAR, newPath, 1); |
| free(newPath); |
| free(c); |
| |
| for (i = 0; i < numPaths; i++) |
| free(paths[i]); |
| free(paths); |
| |
| /* now we must restart for this to take affect*/ |
| restartLauncher(initialArgv[0], initialArgv); |
| } |
| |
| void restartLauncher(char* program, char* args[]) { |
| pid_t pid= fork(); |
| if (pid == 0) { |
| /* Child process ... start the JVM */ |
| execv(program != NULL ? program : args[0], args); |
| |
| /* The JVM would not start ... return error code to parent process. */ |
| _exit(errno); |
| } else { |
| exit(0); |
| } |
| } |
| |
| JavaResults* launchJavaVM( _TCHAR* args[] ) |
| { |
| /* |
| * On macOS, JNI is always used, so this point is only reached, if no usable JVM was found. |
| * Request a JDK install: The 'script' command makes stdin and stdout look like a tty, |
| * so it looks for /usr/libexec/java_home that this is for a command line tool and a dialog |
| * with a link to the JDK download page is shown. |
| */ |
| execl("/usr/bin/script", "/usr/bin/script", "/dev/null", "/usr/libexec/java_home", "--request", NULL); |
| |
| /* not reached. */ |
| JavaResults * results = malloc(sizeof(JavaResults)); |
| results->launchResult = -1; |
| results->runResult = 0; |
| results->errorMessage = _tcsdup(noForkingMsg); |
| return results; |
| } |
| |
| JavaResults* startJavaVM( _TCHAR* libPath, _TCHAR* vmArgs[], _TCHAR* progArgs[], _TCHAR* jarFile ) |
| { |
| return startJavaJNI(libPath, vmArgs, progArgs, jarFile); |
| } |
| |
| #define DOCK_ICON_PREFIX "-Xdock:icon=" |
| #define DOCK_NAME_PREFIX "-Xdock:name=" |
| #define APP_ICON_PATTERN "APP_ICON_%d" |
| #define APP_NAME_PATTERN "APP_NAME_%d" |
| |
| void processVMArgs(char **vmargs[] ) |
| { |
| int i = -1; |
| int pid = 0, pidLength = 1, temp = 0; |
| char * name = NULL, *icon = NULL; |
| char * c; |
| |
| if( *vmargs == NULL) |
| return; |
| |
| while( (*vmargs)[++i] != NULL ) { |
| /*-Xdock:icon -> APP_ICON_<pid>*/ |
| if(_tcsncmp((*vmargs)[i], DOCK_ICON_PREFIX, _tcslen(DOCK_ICON_PREFIX)) == 0) { |
| icon = (*vmargs)[i] + _tcslen(DOCK_ICON_PREFIX); |
| } |
| /*-Xdock:name -> APP_NAME_<pid>*/ |
| else if(_tcsncmp((*vmargs)[i], DOCK_NAME_PREFIX, _tcslen(DOCK_NAME_PREFIX)) == 0) { |
| name = (*vmargs)[i] + _tcslen(DOCK_NAME_PREFIX); |
| } |
| if (name != NULL && icon != NULL) |
| break; |
| } |
| |
| if (name == NULL && icon == NULL) |
| return; /* don't need to do anything */ |
| |
| temp = pid = getpid(); |
| /* how many digits in pid? */ |
| while (temp > 9) { |
| pidLength++; |
| temp /= 10; |
| } |
| |
| if (name != NULL) { |
| c = malloc( (_tcslen(APP_NAME_PATTERN) + pidLength + 1) * sizeof(char*)); |
| _stprintf( c, APP_NAME_PATTERN, pid ); |
| setenv(c, name, 1); |
| } |
| |
| if (icon != NULL) { |
| c = malloc( (_tcslen(icon) + _tcslen(APP_ICON_PATTERN) + pidLength + 1) * sizeof(char*)); |
| _stprintf( c, APP_ICON_PATTERN, pid ); |
| setenv(c, icon, 1); |
| } |
| } |
| |
| int isModularVM( _TCHAR * javaVM, _TCHAR * jniLib ) { |
| return isModularJVM; |
| } |
| |
| NSString* getApplicationSupport() { |
| NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); |
| NSString *documentsDirectory = [paths objectAtIndex:0]; |
| return documentsDirectory; |
| |
| } |
| |
| NSString* getCFBundleIdentifier() { |
| CFBundleRef mainBundle= CFBundleGetMainBundle(); |
| return (NSString*) CFBundleGetIdentifier(mainBundle); |
| } |
| |
| const char* getUUID() { |
| const char * installPath = [[[NSBundle mainBundle] resourcePath] fileSystemRepresentation]; |
| int bufferLength = getxattr(installPath, INSTALL_UUID, NULL, 0, 0, 0); |
| if (bufferLength != -1) { |
| char *buffer = malloc(bufferLength + 1); |
| buffer[bufferLength] = '\0'; |
| getxattr(installPath, INSTALL_UUID, buffer, bufferLength, 0, 0); |
| return buffer; |
| } |
| |
| NSString * timestamp = [NSString stringWithFormat:@"%f",[[NSDate date] timeIntervalSince1970] * 1000]; |
| const char* timestampAsChar = [timestamp UTF8String]; |
| setxattr(installPath, INSTALL_UUID, timestampAsChar, strlen(timestampAsChar), 0, 0); |
| return timestampAsChar; |
| } |
| |
| _TCHAR* getFolderForApplicationData() { |
| NSString* bundleId = getCFBundleIdentifier(); |
| NSString* appSupport = getApplicationSupport(); |
| return [[NSString stringWithFormat:@"%@/%@_%s", appSupport, bundleId, getUUID()] UTF8String]; |
| } |