< prev index next >

jdk/src/java.base/macosx/native/libjli/java_md_macosx.c

Print this page




 154  *  \|/
 155  * Paths have well known
 156  * jvm paths ?       --> NO --> Have Desired Model ? NO --> Re-exec --> Main
 157  *  YES                              YES --> Continue
 158  *   |
 159  *   |
 160  *  \|/
 161  *  Does libjvm.so exist
 162  *  in any of them ? --> NO --> Have Desired Model ? NO --> Re-exec --> Main
 163  *   YES                             YES --> Continue
 164  *   |
 165  *   |
 166  *  \|/
 167  * Re-exec / Spawn
 168  *   |
 169  *   |
 170  *  \|/
 171  * Main
 172  */
 173 
 174 #define GetArch() GetArchPath(CURRENT_DATA_MODEL)
 175 
 176 /* Store the name of the executable once computed */
 177 static char *execname = NULL;
 178 
 179 /*
 180  * execname accessor from other parts of platform dependent logic
 181  */
 182 const char *
 183 GetExecName() {
 184     return execname;
 185 }
 186 
 187 const char *
 188 GetArchPath(int nbits)
 189 {
 190     switch(nbits) {
 191         default:
 192             return LIBARCHNAME;
 193     }
 194 }
 195 
 196 
 197 /*
 198  * Exports the JNI interface from libjli
 199  *
 200  * This allows client code to link against the .jre/.jdk bundles,
 201  * and not worry about trying to pick a HotSpot to link against.
 202  *
 203  * Switching architectures is unsupported, since client code has
 204  * made that choice before the JVM was requested.
 205  */
 206 
 207 static InvocationFunctions *sExportedJNIFunctions = NULL;
 208 static char *sPreferredJVMType = NULL;
 209 
 210 static InvocationFunctions *GetExportedJNIFunctions() {
 211     if (sExportedJNIFunctions != NULL) return sExportedJNIFunctions;
 212 
 213     char jrePath[PATH_MAX];
 214     jboolean gotJREPath = GetJREPath(jrePath, sizeof(jrePath), GetArch(), JNI_FALSE);
 215     if (!gotJREPath) {
 216         JLI_ReportErrorMessage("Failed to GetJREPath()");
 217         return NULL;
 218     }
 219 
 220     char *preferredJVM = sPreferredJVMType;
 221     if (preferredJVM == NULL) {
 222 #if defined(__i386__)
 223         preferredJVM = "client";
 224 #elif defined(__x86_64__)
 225         preferredJVM = "server";
 226 #else
 227 #error "Unknown architecture - needs definition"
 228 #endif
 229     }
 230 
 231     char jvmPath[PATH_MAX];
 232     jboolean gotJVMPath = GetJVMPath(jrePath, preferredJVM, jvmPath, sizeof(jvmPath), GetArch(), CURRENT_DATA_MODEL);
 233     if (!gotJVMPath) {
 234         JLI_ReportErrorMessage("Failed to GetJVMPath()");
 235         return NULL;
 236     }
 237 
 238     InvocationFunctions *fxns = malloc(sizeof(InvocationFunctions));
 239     jboolean vmLoaded = LoadJavaVM(jvmPath, fxns);
 240     if (!vmLoaded) {
 241         JLI_ReportErrorMessage("Failed to LoadJavaVM()");
 242         return NULL;
 243     }
 244 
 245     return sExportedJNIFunctions = fxns;
 246 }
 247 
 248 #ifndef STATIC_BUILD
 249 
 250 JNIEXPORT jint JNICALL
 251 JNI_GetDefaultJavaVMInitArgs(void *args) {
 252     InvocationFunctions *ifn = GetExportedJNIFunctions();


 373 CreateExecutionEnvironment(int *pargc, char ***pargv,
 374                            char jrepath[], jint so_jrepath,
 375                            char jvmpath[], jint so_jvmpath,
 376                            char jvmcfg[],  jint so_jvmcfg) {
 377   /*
 378    * First, determine if we are running the desired data model.  If we
 379    * are running the desired data model, all the error messages
 380    * associated with calling GetJREPath, ReadKnownVMs, etc. should be
 381    * output.  However, if we are not running the desired data model,
 382    * some of the errors should be suppressed since it is more
 383    * informative to issue an error message based on whether or not the
 384    * os/processor combination has dual mode capabilities.
 385    */
 386     jboolean jvmpathExists;
 387 
 388     /* Compute/set the name of the executable */
 389     SetExecname(*pargv);
 390 
 391     /* Check data model flags, and exec process, if needed */
 392     {
 393       char *arch        = (char *)GetArch(); /* like sparc or sparcv9 */
 394       char * jvmtype    = NULL;
 395       int  argc         = *pargc;
 396       char **argv       = *pargv;
 397       int running       = CURRENT_DATA_MODEL;
 398 
 399       int wanted        = running;      /* What data mode is being
 400                                            asked for? Current model is
 401                                            fine unless another model
 402                                            is asked for */
 403 
 404       char** newargv    = NULL;
 405       int    newargc    = 0;
 406 
 407       /*
 408        * Starting in 1.5, all unix platforms accept the -d32 and -d64
 409        * options.  On platforms where only one data-model is supported
 410        * (e.g. ia-64 Linux), using the flag for the other data model is
 411        * an error and will terminate the program.
 412        */
 413 


 445         }
 446 
 447         /* copy rest of args [i .. argc) */
 448         while (i < argc) {
 449           newargv[newargc++] = argv[i++];
 450         }
 451         newargv[newargc] = NULL;
 452 
 453         /*
 454          * newargv has all proper arguments here
 455          */
 456 
 457         argc = newargc;
 458         argv = newargv;
 459       }
 460 
 461       /* If the data model is not changing, it is an error if the
 462          jvmpath does not exist */
 463       if (wanted == running) {
 464         /* Find out where the JRE is that we will be using. */
 465         if (!GetJREPath(jrepath, so_jrepath, arch, JNI_FALSE) ) {
 466           JLI_ReportErrorMessage(JRE_ERROR1);
 467           exit(2);
 468         }
 469         JLI_Snprintf(jvmcfg, so_jvmcfg, "%s%slib%s%s%sjvm.cfg",
 470           jrepath, FILESEP, FILESEP,  "", "");
 471         /* Find the specified JVM type */
 472         if (ReadKnownVMs(jvmcfg, JNI_FALSE) < 1) {
 473           JLI_ReportErrorMessage(CFG_ERROR7);
 474           exit(1);
 475         }
 476 
 477         jvmpath[0] = '\0';
 478         jvmtype = CheckJvmType(pargc, pargv, JNI_FALSE);
 479         if (JLI_StrCmp(jvmtype, "ERROR") == 0) {
 480             JLI_ReportErrorMessage(CFG_ERROR9);
 481             exit(4);
 482         }
 483 
 484         if (!GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, arch, wanted)) {
 485           JLI_ReportErrorMessage(CFG_ERROR8, jvmtype, jvmpath);
 486           exit(4);
 487         }
 488 
 489         /*
 490          * Mac OS X requires the Cocoa event loop to be run on the "main"
 491          * thread. Spawn off a new thread to run main() and pass
 492          * this thread off to the Cocoa event loop.
 493          */
 494         MacOSXStartup(argc, argv);
 495 
 496         /*
 497          * we seem to have everything we need, so without further ado
 498          * we return back, otherwise proceed to set the environment.
 499          */
 500         return;
 501       } else {  /* do the same speculatively or exit */
 502 #if defined(DUAL_MODE)
 503         if (running != wanted) {
 504           /* Find out where the JRE is that we will be using. */
 505           if (!GetJREPath(jrepath, so_jrepath, GetArchPath(wanted), JNI_TRUE)) {
 506             /* give up and let other code report error message */
 507             JLI_ReportErrorMessage(JRE_ERROR2, wanted);
 508             exit(1);
 509           }
 510           JLI_Snprintf(jvmcfg, so_jvmcfg, "%s%slib%s%s%sjvm.cfg",
 511             jrepath, FILESEP, FILESEP,  "", "");
 512           /*
 513            * Read in jvm.cfg for target data model and process vm
 514            * selection options.
 515            */
 516           if (ReadKnownVMs(jvmcfg, JNI_TRUE) < 1) {
 517             /* give up and let other code report error message */
 518             JLI_ReportErrorMessage(JRE_ERROR2, wanted);
 519             exit(1);
 520           }
 521           jvmpath[0] = '\0';
 522           jvmtype = CheckJvmType(pargc, pargv, JNI_TRUE);
 523           if (JLI_StrCmp(jvmtype, "ERROR") == 0) {
 524             JLI_ReportErrorMessage(CFG_ERROR9);
 525             exit(4);
 526           }
 527 
 528           /* exec child can do error checking on the existence of the path */
 529           jvmpathExists = GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, GetArchPath(wanted), wanted);
 530         }
 531 #else /* ! DUAL_MODE */
 532         JLI_ReportErrorMessage(JRE_ERROR2, wanted);
 533         exit(1);
 534 #endif /* DUAL_MODE */
 535         }
 536         {
 537             char *newexec = execname;
 538             JLI_TraceLauncher("TRACER_MARKER:About to EXEC\n");
 539             (void) fflush(stdout);
 540             (void) fflush(stderr);
 541             /*
 542             * Use posix_spawn() instead of execv() on Mac OS X.
 543             * This allows us to choose which architecture the child process
 544             * should run as.
 545             */
 546             {
 547                 posix_spawnattr_t attr;
 548                 size_t unused_size;
 549                 pid_t  unused_pid;


 562 
 563                 posix_spawn(&unused_pid, newexec, NULL, &attr, argv, environ);
 564             }
 565             JLI_ReportErrorMessageSys(JRE_ERROR4, newexec);
 566 
 567 #if defined(DUAL_MODE)
 568             if (running != wanted) {
 569                 JLI_ReportErrorMessage(JRE_ERROR5, wanted, running);
 570             }
 571 #endif /* DUAL_MODE */
 572         }
 573         exit(1);
 574     }
 575 }
 576 
 577 /*
 578  * VM choosing is done by the launcher (java.c).
 579  */
 580 static jboolean
 581 GetJVMPath(const char *jrepath, const char *jvmtype,
 582            char *jvmpath, jint jvmpathsize, const char * arch, int bitsWanted)
 583 {
 584     struct stat s;
 585 
 586     if (JLI_StrChr(jvmtype, '/')) {
 587         JLI_Snprintf(jvmpath, jvmpathsize, "%s/" JVM_DLL, jvmtype);
 588     } else {
 589         /*
 590          * macosx client library is built thin, i386 only.
 591          * 64 bit client requests must load server library
 592          */
 593         const char *jvmtypeUsed = ((bitsWanted == 64) && (strcmp(jvmtype, "client") == 0)) ? "server" : jvmtype;
 594         JLI_Snprintf(jvmpath, jvmpathsize, "%s/lib/%s/" JVM_DLL, jrepath, jvmtypeUsed);
 595     }
 596 
 597     JLI_TraceLauncher("Does `%s' exist ... ", jvmpath);
 598 
 599 #ifdef STATIC_BUILD
 600     return JNI_TRUE;
 601 #else
 602     if (stat(jvmpath, &s) == 0) {
 603         JLI_TraceLauncher("yes.\n");
 604         return JNI_TRUE;
 605     } else {
 606         JLI_TraceLauncher("no.\n");
 607         return JNI_FALSE;
 608     }
 609 #endif
 610 }
 611 
 612 /*
 613  * Find path to JRE based on .exe's location or registry settings.
 614  */
 615 static jboolean
 616 GetJREPath(char *path, jint pathsize, const char * arch, jboolean speculative)
 617 {
 618     char libjava[MAXPATHLEN];
 619 
 620     if (GetApplicationHome(path, pathsize)) {
 621         /* Is JRE co-located with the application? */
 622 #ifdef STATIC_BUILD
 623         char jvm_cfg[MAXPATHLEN];
 624         JLI_Snprintf(jvm_cfg, sizeof(jvm_cfg), "%s/lib/jvm.cfg", path);
 625         if (access(jvm_cfg, F_OK) == 0) {
 626             return JNI_TRUE;
 627         }
 628 #else
 629         JLI_Snprintf(libjava, sizeof(libjava), "%s/lib/" JAVA_DLL, path);
 630         if (access(libjava, F_OK) == 0) {
 631             return JNI_TRUE;
 632         }
 633 #endif
 634         /* ensure storage for path + /jre + NULL */
 635         if ((JLI_StrLen(path) + 4 + 1) > (size_t) pathsize) {
 636             JLI_TraceLauncher("Insufficient space to store JRE path\n");


 824             if (OSXAPP_SetJavaVM) {
 825                 OSXAPP_SetJavaVM(jvm);
 826             } else {
 827                 jvm = NULL;
 828             }
 829         }
 830 
 831         dlclose(handle);
 832     }
 833 
 834     return jvm;
 835 }
 836 
 837 static const char* SPLASHSCREEN_SO = JNI_LIB_NAME("splashscreen");
 838 
 839 static void* hSplashLib = NULL;
 840 
 841 void* SplashProcAddress(const char* name) {
 842     if (!hSplashLib) {
 843         char jrePath[PATH_MAX];
 844         if (!GetJREPath(jrePath, sizeof(jrePath), GetArch(), JNI_FALSE)) {
 845             JLI_ReportErrorMessage(JRE_ERROR1);
 846             return NULL;
 847         }
 848 
 849         char splashPath[PATH_MAX];
 850         const int ret = JLI_Snprintf(splashPath, sizeof(splashPath),
 851                 "%s/lib/%s", jrePath, SPLASHSCREEN_SO);
 852         if (ret >= (int)sizeof(splashPath)) {
 853             JLI_ReportErrorMessage(JRE_ERROR11);
 854             return NULL;
 855         }
 856         if (ret < 0) {
 857             JLI_ReportErrorMessage(JRE_ERROR13);
 858             return NULL;
 859         }
 860 
 861         hSplashLib = dlopen(splashPath, RTLD_LAZY | RTLD_GLOBAL);
 862         // It's OK if dlopen() fails. The splash screen library binary file
 863         // might have been stripped out from the JRE image to reduce its size
 864         // (e.g. on embedded platforms).




 154  *  \|/
 155  * Paths have well known
 156  * jvm paths ?       --> NO --> Have Desired Model ? NO --> Re-exec --> Main
 157  *  YES                              YES --> Continue
 158  *   |
 159  *   |
 160  *  \|/
 161  *  Does libjvm.so exist
 162  *  in any of them ? --> NO --> Have Desired Model ? NO --> Re-exec --> Main
 163  *   YES                             YES --> Continue
 164  *   |
 165  *   |
 166  *  \|/
 167  * Re-exec / Spawn
 168  *   |
 169  *   |
 170  *  \|/
 171  * Main
 172  */
 173 


 174 /* Store the name of the executable once computed */
 175 static char *execname = NULL;
 176 
 177 /*
 178  * execname accessor from other parts of platform dependent logic
 179  */
 180 const char *
 181 GetExecName() {
 182     return execname;
 183 }
 184 










 185 /*
 186  * Exports the JNI interface from libjli
 187  *
 188  * This allows client code to link against the .jre/.jdk bundles,
 189  * and not worry about trying to pick a HotSpot to link against.
 190  *
 191  * Switching architectures is unsupported, since client code has
 192  * made that choice before the JVM was requested.
 193  */
 194 
 195 static InvocationFunctions *sExportedJNIFunctions = NULL;
 196 static char *sPreferredJVMType = NULL;
 197 
 198 static InvocationFunctions *GetExportedJNIFunctions() {
 199     if (sExportedJNIFunctions != NULL) return sExportedJNIFunctions;
 200 
 201     char jrePath[PATH_MAX];
 202     jboolean gotJREPath = GetJREPath(jrePath, sizeof(jrePath), JNI_FALSE);
 203     if (!gotJREPath) {
 204         JLI_ReportErrorMessage("Failed to GetJREPath()");
 205         return NULL;
 206     }
 207 
 208     char *preferredJVM = sPreferredJVMType;
 209     if (preferredJVM == NULL) {
 210 #if defined(__i386__)
 211         preferredJVM = "client";
 212 #elif defined(__x86_64__)
 213         preferredJVM = "server";
 214 #else
 215 #error "Unknown architecture - needs definition"
 216 #endif
 217     }
 218 
 219     char jvmPath[PATH_MAX];
 220     jboolean gotJVMPath = GetJVMPath(jrePath, preferredJVM, jvmPath, sizeof(jvmPath), CURRENT_DATA_MODEL);
 221     if (!gotJVMPath) {
 222         JLI_ReportErrorMessage("Failed to GetJVMPath()");
 223         return NULL;
 224     }
 225 
 226     InvocationFunctions *fxns = malloc(sizeof(InvocationFunctions));
 227     jboolean vmLoaded = LoadJavaVM(jvmPath, fxns);
 228     if (!vmLoaded) {
 229         JLI_ReportErrorMessage("Failed to LoadJavaVM()");
 230         return NULL;
 231     }
 232 
 233     return sExportedJNIFunctions = fxns;
 234 }
 235 
 236 #ifndef STATIC_BUILD
 237 
 238 JNIEXPORT jint JNICALL
 239 JNI_GetDefaultJavaVMInitArgs(void *args) {
 240     InvocationFunctions *ifn = GetExportedJNIFunctions();


 361 CreateExecutionEnvironment(int *pargc, char ***pargv,
 362                            char jrepath[], jint so_jrepath,
 363                            char jvmpath[], jint so_jvmpath,
 364                            char jvmcfg[],  jint so_jvmcfg) {
 365   /*
 366    * First, determine if we are running the desired data model.  If we
 367    * are running the desired data model, all the error messages
 368    * associated with calling GetJREPath, ReadKnownVMs, etc. should be
 369    * output.  However, if we are not running the desired data model,
 370    * some of the errors should be suppressed since it is more
 371    * informative to issue an error message based on whether or not the
 372    * os/processor combination has dual mode capabilities.
 373    */
 374     jboolean jvmpathExists;
 375 
 376     /* Compute/set the name of the executable */
 377     SetExecname(*pargv);
 378 
 379     /* Check data model flags, and exec process, if needed */
 380     {

 381       char * jvmtype    = NULL;
 382       int  argc         = *pargc;
 383       char **argv       = *pargv;
 384       int running       = CURRENT_DATA_MODEL;
 385 
 386       int wanted        = running;      /* What data mode is being
 387                                            asked for? Current model is
 388                                            fine unless another model
 389                                            is asked for */
 390 
 391       char** newargv    = NULL;
 392       int    newargc    = 0;
 393 
 394       /*
 395        * Starting in 1.5, all unix platforms accept the -d32 and -d64
 396        * options.  On platforms where only one data-model is supported
 397        * (e.g. ia-64 Linux), using the flag for the other data model is
 398        * an error and will terminate the program.
 399        */
 400 


 432         }
 433 
 434         /* copy rest of args [i .. argc) */
 435         while (i < argc) {
 436           newargv[newargc++] = argv[i++];
 437         }
 438         newargv[newargc] = NULL;
 439 
 440         /*
 441          * newargv has all proper arguments here
 442          */
 443 
 444         argc = newargc;
 445         argv = newargv;
 446       }
 447 
 448       /* If the data model is not changing, it is an error if the
 449          jvmpath does not exist */
 450       if (wanted == running) {
 451         /* Find out where the JRE is that we will be using. */
 452         if (!GetJREPath(jrepath, so_jrepath, JNI_FALSE) ) {
 453           JLI_ReportErrorMessage(JRE_ERROR1);
 454           exit(2);
 455         }
 456         JLI_Snprintf(jvmcfg, so_jvmcfg, "%s%slib%s%s%sjvm.cfg",
 457           jrepath, FILESEP, FILESEP,  "", "");
 458         /* Find the specified JVM type */
 459         if (ReadKnownVMs(jvmcfg, JNI_FALSE) < 1) {
 460           JLI_ReportErrorMessage(CFG_ERROR7);
 461           exit(1);
 462         }
 463 
 464         jvmpath[0] = '\0';
 465         jvmtype = CheckJvmType(pargc, pargv, JNI_FALSE);
 466         if (JLI_StrCmp(jvmtype, "ERROR") == 0) {
 467             JLI_ReportErrorMessage(CFG_ERROR9);
 468             exit(4);
 469         }
 470 
 471         if (!GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, wanted)) {
 472           JLI_ReportErrorMessage(CFG_ERROR8, jvmtype, jvmpath);
 473           exit(4);
 474         }
 475 
 476         /*
 477          * Mac OS X requires the Cocoa event loop to be run on the "main"
 478          * thread. Spawn off a new thread to run main() and pass
 479          * this thread off to the Cocoa event loop.
 480          */
 481         MacOSXStartup(argc, argv);
 482 
 483         /*
 484          * we seem to have everything we need, so without further ado
 485          * we return back, otherwise proceed to set the environment.
 486          */
 487         return;
 488       } else {  /* do the same speculatively or exit */
 489 #if defined(DUAL_MODE)
 490         if (running != wanted) {
 491           /* Find out where the JRE is that we will be using. */
 492           if (!GetJREPath(jrepath, so_jrepath, JNI_TRUE)) {
 493             /* give up and let other code report error message */
 494             JLI_ReportErrorMessage(JRE_ERROR2, wanted);
 495             exit(1);
 496           }
 497           JLI_Snprintf(jvmcfg, so_jvmcfg, "%s%slib%s%s%sjvm.cfg",
 498             jrepath, FILESEP, FILESEP,  "", "");
 499           /*
 500            * Read in jvm.cfg for target data model and process vm
 501            * selection options.
 502            */
 503           if (ReadKnownVMs(jvmcfg, JNI_TRUE) < 1) {
 504             /* give up and let other code report error message */
 505             JLI_ReportErrorMessage(JRE_ERROR2, wanted);
 506             exit(1);
 507           }
 508           jvmpath[0] = '\0';
 509           jvmtype = CheckJvmType(pargc, pargv, JNI_TRUE);
 510           if (JLI_StrCmp(jvmtype, "ERROR") == 0) {
 511             JLI_ReportErrorMessage(CFG_ERROR9);
 512             exit(4);
 513           }
 514 
 515           /* exec child can do error checking on the existence of the path */
 516           jvmpathExists = GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, wanted);
 517         }
 518 #else /* ! DUAL_MODE */
 519         JLI_ReportErrorMessage(JRE_ERROR2, wanted);
 520         exit(1);
 521 #endif /* DUAL_MODE */
 522         }
 523         {
 524             char *newexec = execname;
 525             JLI_TraceLauncher("TRACER_MARKER:About to EXEC\n");
 526             (void) fflush(stdout);
 527             (void) fflush(stderr);
 528             /*
 529             * Use posix_spawn() instead of execv() on Mac OS X.
 530             * This allows us to choose which architecture the child process
 531             * should run as.
 532             */
 533             {
 534                 posix_spawnattr_t attr;
 535                 size_t unused_size;
 536                 pid_t  unused_pid;


 549 
 550                 posix_spawn(&unused_pid, newexec, NULL, &attr, argv, environ);
 551             }
 552             JLI_ReportErrorMessageSys(JRE_ERROR4, newexec);
 553 
 554 #if defined(DUAL_MODE)
 555             if (running != wanted) {
 556                 JLI_ReportErrorMessage(JRE_ERROR5, wanted, running);
 557             }
 558 #endif /* DUAL_MODE */
 559         }
 560         exit(1);
 561     }
 562 }
 563 
 564 /*
 565  * VM choosing is done by the launcher (java.c).
 566  */
 567 static jboolean
 568 GetJVMPath(const char *jrepath, const char *jvmtype,
 569            char *jvmpath, jint jvmpathsize, int bitsWanted)
 570 {
 571     struct stat s;
 572 
 573     if (JLI_StrChr(jvmtype, '/')) {
 574         JLI_Snprintf(jvmpath, jvmpathsize, "%s/" JVM_DLL, jvmtype);
 575     } else {
 576         /*
 577          * macosx client library is built thin, i386 only.
 578          * 64 bit client requests must load server library
 579          */
 580         const char *jvmtypeUsed = ((bitsWanted == 64) && (strcmp(jvmtype, "client") == 0)) ? "server" : jvmtype;
 581         JLI_Snprintf(jvmpath, jvmpathsize, "%s/lib/%s/" JVM_DLL, jrepath, jvmtypeUsed);
 582     }
 583 
 584     JLI_TraceLauncher("Does `%s' exist ... ", jvmpath);
 585 
 586 #ifdef STATIC_BUILD
 587     return JNI_TRUE;
 588 #else
 589     if (stat(jvmpath, &s) == 0) {
 590         JLI_TraceLauncher("yes.\n");
 591         return JNI_TRUE;
 592     } else {
 593         JLI_TraceLauncher("no.\n");
 594         return JNI_FALSE;
 595     }
 596 #endif
 597 }
 598 
 599 /*
 600  * Find path to JRE based on .exe's location or registry settings.
 601  */
 602 static jboolean
 603 GetJREPath(char *path, jint pathsize, jboolean speculative)
 604 {
 605     char libjava[MAXPATHLEN];
 606 
 607     if (GetApplicationHome(path, pathsize)) {
 608         /* Is JRE co-located with the application? */
 609 #ifdef STATIC_BUILD
 610         char jvm_cfg[MAXPATHLEN];
 611         JLI_Snprintf(jvm_cfg, sizeof(jvm_cfg), "%s/lib/jvm.cfg", path);
 612         if (access(jvm_cfg, F_OK) == 0) {
 613             return JNI_TRUE;
 614         }
 615 #else
 616         JLI_Snprintf(libjava, sizeof(libjava), "%s/lib/" JAVA_DLL, path);
 617         if (access(libjava, F_OK) == 0) {
 618             return JNI_TRUE;
 619         }
 620 #endif
 621         /* ensure storage for path + /jre + NULL */
 622         if ((JLI_StrLen(path) + 4 + 1) > (size_t) pathsize) {
 623             JLI_TraceLauncher("Insufficient space to store JRE path\n");


 811             if (OSXAPP_SetJavaVM) {
 812                 OSXAPP_SetJavaVM(jvm);
 813             } else {
 814                 jvm = NULL;
 815             }
 816         }
 817 
 818         dlclose(handle);
 819     }
 820 
 821     return jvm;
 822 }
 823 
 824 static const char* SPLASHSCREEN_SO = JNI_LIB_NAME("splashscreen");
 825 
 826 static void* hSplashLib = NULL;
 827 
 828 void* SplashProcAddress(const char* name) {
 829     if (!hSplashLib) {
 830         char jrePath[PATH_MAX];
 831         if (!GetJREPath(jrePath, sizeof(jrePath), JNI_FALSE)) {
 832             JLI_ReportErrorMessage(JRE_ERROR1);
 833             return NULL;
 834         }
 835 
 836         char splashPath[PATH_MAX];
 837         const int ret = JLI_Snprintf(splashPath, sizeof(splashPath),
 838                 "%s/lib/%s", jrePath, SPLASHSCREEN_SO);
 839         if (ret >= (int)sizeof(splashPath)) {
 840             JLI_ReportErrorMessage(JRE_ERROR11);
 841             return NULL;
 842         }
 843         if (ret < 0) {
 844             JLI_ReportErrorMessage(JRE_ERROR13);
 845             return NULL;
 846         }
 847 
 848         hSplashLib = dlopen(splashPath, RTLD_LAZY | RTLD_GLOBAL);
 849         // It's OK if dlopen() fails. The splash screen library binary file
 850         // might have been stripped out from the JRE image to reduce its size
 851         // (e.g. on embedded platforms).


< prev index next >