jdk/src/solaris/bin/java_md.c
changeset 9244 84d85c90d5db
parent 7028 adadd244f506
child 10706 9bd5de10aaf9
equal deleted inserted replaced
9243:d7a77bce0742 9244:84d85c90d5db
     1 /*
     1 /*
     2  * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    44 #endif
    44 #endif
    45 
    45 
    46 #define JVM_DLL "libjvm.so"
    46 #define JVM_DLL "libjvm.so"
    47 #define JAVA_DLL "libjava.so"
    47 #define JAVA_DLL "libjava.so"
    48 
    48 
       
    49 /* help jettison the LD_LIBRARY_PATH settings in the future */
       
    50 #ifndef SETENV_REQUIRED
       
    51 #define SETENV_REQUIRED
       
    52 #endif
    49 /*
    53 /*
    50  * If a processor / os combination has the ability to run binaries of
    54  * If a processor / os combination has the ability to run binaries of
    51  * two data models and cohabitation of jre/jdk bits with both data
    55  * two data models and cohabitation of jre/jdk bits with both data
    52  * models is supported, then DUAL_MODE is defined.  When DUAL_MODE is
    56  * models is supported, then DUAL_MODE is defined.  When DUAL_MODE is
    53  * defined, the architecture names for the narrow and wide version of
    57  * defined, the architecture names for the narrow and wide version of
   104  * the exec of the specified launcher version.
   108  * the exec of the specified launcher version.
   105  *
   109  *
   106  * Previously the launcher modified the LD_LIBRARY_PATH appropriately for the
   110  * Previously the launcher modified the LD_LIBRARY_PATH appropriately for the
   107  * desired data model path, regardless if data models matched or not. The
   111  * desired data model path, regardless if data models matched or not. The
   108  * launcher subsequently exec'ed the desired executable, in order to make the
   112  * launcher subsequently exec'ed the desired executable, in order to make the
   109  * LD_LIBRARY_PATH path available for the runtime linker. This is no longer the
   113  * LD_LIBRARY_PATH path available, for the runtime linker.
   110  * case, the launcher dlopens the target libjvm.so. All other required
   114  *
   111  * libraries are loaded by the runtime linker, by virtue of the $ORIGIN paths
   115  * Now, in most cases,the launcher will dlopen the target libjvm.so. All
   112  * baked into the shared libraries, by the build infrastructure at compile time.
   116  * required libraries are loaded by the runtime linker, using the
       
   117  * $RPATH/$ORIGIN baked into the shared libraries at compile time. Therefore,
       
   118  * in most cases, the launcher will only exec, if the data models are
       
   119  * mismatched, and will not set any environment variables, regardless of the
       
   120  * data models.
       
   121  *
       
   122  * However, if the environment contains a LD_LIBRARY_PATH, this will cause the
       
   123  * launcher to inspect the LD_LIBRARY_PATH. The launcher will check
       
   124  *  a. if the LD_LIBRARY_PATH's first component is the the path to the desired
       
   125  *     libjvm.so
       
   126  *  b. if any other libjvm.so is found in any of the paths.
       
   127  * If case b is true, then the launcher will set the LD_LIBRARY_PATH to the
       
   128  * desired JRE and reexec, in order to propagate the environment.
   113  *
   129  *
   114  *  Main
   130  *  Main
   115  *  (incoming argv)
   131  *  (incoming argv)
   116  *  |
   132  *  |
   117  * \|/
   133  * \|/
   135  *  |                                CheckJvmType
   151  *  |                                CheckJvmType
   136  *  |                               (removes -client, -server etc.)
   152  *  |                               (removes -client, -server etc.)
   137  *  |                                          |
   153  *  |                                          |
   138  *  |                                          |
   154  *  |                                          |
   139  * \|/                                        \|/
   155  * \|/                                        \|/
   140  * YES                              (find the desired executable and exec child)
   156  * YES                             Find the desired executable/library
   141  *  |                                          |
   157  *  |                                          |
   142  *  |                                          |
   158  *  |                                          |
   143  * \|/                                        \|/
   159  * \|/                                        \|/
   144  * CheckJvmType                                Main
   160  * CheckJvmType                          RequiresSetenv
   145  * (removes -client, -server, etc.)
   161  * (removes -client, -server, etc.)
   146  *  |
   162  *  |
   147  *  |
   163  *  |
   148  * \|/
   164  * \|/
   149  * TranslateDashJArgs...
   165  * TranslateDashJArgs...
   154  * ParseArguments
   170  * ParseArguments
   155  * (removes -d32 and -d64 if any,
   171  * (removes -d32 and -d64 if any,
   156  *  processes version options,
   172  *  processes version options,
   157  *  creates argument list for vm,
   173  *  creates argument list for vm,
   158  *  etc.)
   174  *  etc.)
   159  *
   175  *   |
       
   176  *   |
       
   177  *  \|/
       
   178  * RequiresSetenv
       
   179  * Is LD_LIBRARY_PATH
       
   180  * and friends set ? --> NO --> Have Desired Model ? NO --> Re-exec --> Main
       
   181  *  YES                              YES --> Continue
       
   182  *   |
       
   183  *   |
       
   184  *  \|/
       
   185  * Path is desired JRE ? YES --> Have Desired Model ? NO --> Re-exec --> Main
       
   186  *  NO                               YES --> Continue
       
   187  *   |
       
   188  *   |
       
   189  *  \|/
       
   190  * Paths have well known
       
   191  * jvm paths ?       --> NO --> Have Desired Model ? NO --> Re-exec --> Main
       
   192  *  YES                              YES --> Continue
       
   193  *   |
       
   194  *   |
       
   195  *  \|/
       
   196  *  Does libjvm.so exit
       
   197  *  in any of them ? --> NO --> Have Desired Model ? NO --> Re-exec --> Main
       
   198  *   YES                             YES --> Continue
       
   199  *   |
       
   200  *   |
       
   201  *  \|/
       
   202  *  Set the LD_LIBRARY_PATH
       
   203  *   |
       
   204  *   |
       
   205  *  \|/
       
   206  * Re-exec
       
   207  *   |
       
   208  *   |
       
   209  *  \|/
       
   210  * Main
   160  */
   211  */
   161 
   212 
   162 static const char * SetExecname(char **argv);
   213 static const char * SetExecname(char **argv);
   163 static jboolean GetJVMPath(const char *jrepath, const char *jvmtype,
   214 static jboolean GetJVMPath(const char *jrepath, const char *jvmtype,
   164                            char *jvmpath, jint jvmpathsize, const char * arch);
   215                            char *jvmpath, jint jvmpathsize, const char * arch);
   179 #endif /* DUAL_MODE */
   230 #endif /* DUAL_MODE */
   180         default:
   231         default:
   181             return LIBARCHNAME;
   232             return LIBARCHNAME;
   182     }
   233     }
   183 }
   234 }
       
   235 
       
   236 #ifdef SETENV_REQUIRED
       
   237 static jboolean
       
   238 JvmExists(const char *path) {
       
   239     char tmp[PATH_MAX + 1];
       
   240     struct stat statbuf;
       
   241     JLI_Snprintf(tmp, PATH_MAX, "%s/%s", path, JVM_DLL);
       
   242     if (stat(tmp, &statbuf) == 0) {
       
   243         return JNI_TRUE;
       
   244     }
       
   245     return JNI_FALSE;
       
   246 }
       
   247 /*
       
   248  * contains a lib/$LIBARCH/{server,client}/libjvm.so ?
       
   249  */
       
   250 static jboolean
       
   251 ContainsLibJVM(int wanted, const char *env) {
       
   252     char clientPattern[PATH_MAX + 1];
       
   253     char serverPattern[PATH_MAX + 1];
       
   254     char *envpath;
       
   255     char *path;
       
   256     jboolean clientPatternFound;
       
   257     jboolean serverPatternFound;
       
   258 
       
   259     /* fastest path */
       
   260     if (env == NULL) {
       
   261         return JNI_FALSE;
       
   262     }
       
   263 
       
   264     /* the usual suspects */
       
   265     JLI_Snprintf(clientPattern, PATH_MAX, "lib/%s/client", GetArchPath(wanted));
       
   266     JLI_Snprintf(serverPattern, PATH_MAX, "lib/%s/server", GetArchPath(wanted));
       
   267 
       
   268     /* to optimize for time, test if any of our usual suspects are present. */
       
   269     clientPatternFound = JLI_StrStr(env, clientPattern) != NULL;
       
   270     serverPatternFound = JLI_StrStr(env, serverPattern) != NULL;
       
   271     if (clientPatternFound == JNI_FALSE && serverPatternFound == JNI_FALSE) {
       
   272         return JNI_FALSE;
       
   273     }
       
   274 
       
   275     /*
       
   276      * we have a suspicious path component, check if it contains a libjvm.so
       
   277      */
       
   278     envpath = JLI_StringDup(env);
       
   279     for (path = JLI_StrTok(envpath, ":"); path != NULL; path = JLI_StrTok(NULL, ":")) {
       
   280         if (clientPatternFound && JLI_StrStr(path, clientPattern) != NULL) {
       
   281             if (JvmExists(path)) {
       
   282                 JLI_MemFree(envpath);
       
   283                 return JNI_TRUE;
       
   284             }
       
   285         }
       
   286         if (serverPatternFound && JLI_StrStr(path, serverPattern)  != NULL) {
       
   287             if (JvmExists(path)) {
       
   288                 JLI_MemFree(envpath);
       
   289                 return JNI_TRUE;
       
   290             }
       
   291         }
       
   292     }
       
   293     JLI_MemFree(envpath);
       
   294     return JNI_FALSE;
       
   295 }
       
   296 
       
   297 /*
       
   298  * Test whether the environment variable needs to be set, see flowchart.
       
   299  */
       
   300 static jboolean
       
   301 RequiresSetenv(int wanted, const char *jvmpath) {
       
   302     char jpath[PATH_MAX + 1];
       
   303     char *llp;
       
   304     char *dmllp = NULL;
       
   305     char *p; /* a utility pointer */
       
   306 
       
   307     llp = getenv("LD_LIBRARY_PATH");
       
   308 #ifdef __solaris__
       
   309     dmllp = (CURRENT_DATA_MODEL == 32)
       
   310             ? getenv("LD_LIBRARY_PATH_32")
       
   311             : getenv("LD_LIBRARY_PATH_64");
       
   312 #endif /* __solaris__ */
       
   313     /* no environment variable is a good environment variable */
       
   314     if (llp == NULL && dmllp == NULL) {
       
   315         return JNI_FALSE;
       
   316     }
       
   317 #ifdef __linux
       
   318     /*
       
   319      * On linux, if a binary is running as sgid or suid, glibc sets
       
   320      * LD_LIBRARY_PATH to the empty string for security purposes. (In contrast,
       
   321      * on Solaris the LD_LIBRARY_PATH variable for a privileged binary does not
       
   322      * lose its settings; but the dynamic linker does apply more scrutiny to the
       
   323      * path.) The launcher uses the value of LD_LIBRARY_PATH to prevent an exec
       
   324      * loop, here and further downstream. Therefore, if we are running sgid or
       
   325      * suid, this function's setting of LD_LIBRARY_PATH will be ineffective and
       
   326      * we should case a return from the calling function.  Getting the right
       
   327      * libraries will be handled by the RPATH. In reality, this check is
       
   328      * redundant, as the previous check for a non-null LD_LIBRARY_PATH will
       
   329      * return back to the calling function forthwith, it is left here to safe
       
   330      * guard against any changes, in the glibc's existing security policy.
       
   331      */
       
   332     if ((getgid() != getegid()) || (getuid() != geteuid())) {
       
   333         return JNI_FALSE;
       
   334     }
       
   335 #endif /* __linux */
       
   336 
       
   337     /*
       
   338      * Prevent recursions. Since LD_LIBRARY_PATH is the one which will be set by
       
   339      * previous versions of the JRE, thus it is the only path that matters here.
       
   340      * So we check to see if the desired JRE is set.
       
   341      */
       
   342     JLI_StrNCpy(jpath, jvmpath, PATH_MAX);
       
   343     p = JLI_StrRChr(jpath, '/');
       
   344     *p = '\0';
       
   345     if (llp != NULL && JLI_StrNCmp(llp, jpath, JLI_StrLen(jpath)) == 0) {
       
   346         return JNI_FALSE;
       
   347     }
       
   348 
       
   349     /* scrutinize all the paths further */
       
   350     if (llp != NULL &&  ContainsLibJVM(wanted, llp)) {
       
   351         return JNI_TRUE;
       
   352     }
       
   353     if (dmllp != NULL && ContainsLibJVM(wanted, dmllp)) {
       
   354         return JNI_TRUE;
       
   355     }
       
   356     return JNI_FALSE;
       
   357 }
       
   358 #endif /* SETENV_REQUIRED */
   184 
   359 
   185 void
   360 void
   186 CreateExecutionEnvironment(int *pargc, char ***pargv,
   361 CreateExecutionEnvironment(int *pargc, char ***pargv,
   187                            char jrepath[], jint so_jrepath,
   362                            char jrepath[], jint so_jrepath,
   188                            char jvmpath[], jint so_jvmpath) {
   363                            char jvmpath[], jint so_jvmpath) {
   193    * output.  However, if we are not running the desired data model,
   368    * output.  However, if we are not running the desired data model,
   194    * some of the errors should be suppressed since it is more
   369    * some of the errors should be suppressed since it is more
   195    * informative to issue an error message based on whether or not the
   370    * informative to issue an error message based on whether or not the
   196    * os/processor combination has dual mode capabilities.
   371    * os/processor combination has dual mode capabilities.
   197    */
   372    */
   198 
       
   199     jboolean jvmpathExists;
   373     jboolean jvmpathExists;
   200 
   374 
   201     /* Compute/set the name of the executable */
   375     /* Compute/set the name of the executable */
   202     SetExecname(*pargv);
   376     SetExecname(*pargv);
   203 
   377 
   205     {
   379     {
   206       char *arch        = (char *)GetArch(); /* like sparc or sparcv9 */
   380       char *arch        = (char *)GetArch(); /* like sparc or sparcv9 */
   207       char * jvmtype    = NULL;
   381       char * jvmtype    = NULL;
   208       int  argc         = *pargc;
   382       int  argc         = *pargc;
   209       char **argv       = *pargv;
   383       char **argv       = *pargv;
   210 
       
   211       int running       = CURRENT_DATA_MODEL;
   384       int running       = CURRENT_DATA_MODEL;
   212 
   385 
   213       int wanted        = running;      /* What data mode is being
   386       int wanted        = running;      /* What data mode is being
   214                                            asked for? Current model is
   387                                            asked for? Current model is
   215                                            fine unless another model
   388                                            fine unless another model
   216                                            is asked for */
   389                                            is asked for */
       
   390 #ifdef SETENV_REQUIRED
       
   391       jboolean mustsetenv = JNI_FALSE;
       
   392       char *runpath     = NULL; /* existing effective LD_LIBRARY_PATH setting */
       
   393       char* new_runpath = NULL; /* desired new LD_LIBRARY_PATH string */
       
   394       char* newpath     = NULL; /* path on new LD_LIBRARY_PATH */
       
   395       char* lastslash   = NULL;
       
   396       char** newenvp    = NULL; /* current environment */
       
   397 #ifdef __solaris__
       
   398       char*  dmpath     = NULL;  /* data model specific LD_LIBRARY_PATH,
       
   399                                     Solaris only */
       
   400 #endif /* __solaris__ */
       
   401 #endif  /* SETENV_REQUIRED */
   217 
   402 
   218       char** newargv    = NULL;
   403       char** newargv    = NULL;
   219       int    newargc    = 0;
   404       int    newargc    = 0;
   220 
   405 
   221       /*
   406       /*
   298           JLI_ReportErrorMessage(CFG_ERROR8, jvmtype, jvmpath);
   483           JLI_ReportErrorMessage(CFG_ERROR8, jvmtype, jvmpath);
   299           exit(4);
   484           exit(4);
   300         }
   485         }
   301         /*
   486         /*
   302          * we seem to have everything we need, so without further ado
   487          * we seem to have everything we need, so without further ado
   303          * we return back.
   488          * we return back, otherwise proceed to set the environment.
   304          */
   489          */
       
   490 #ifdef SETENV_REQUIRED
       
   491         mustsetenv = RequiresSetenv(wanted, jvmpath);
       
   492         JLI_TraceLauncher("mustsetenv: %s\n", mustsetenv ? "TRUE" : "FALSE");
       
   493 
       
   494         if (mustsetenv == JNI_FALSE) {
       
   495             return;
       
   496         }
       
   497 #else
   305         return;
   498         return;
       
   499 #endif /* SETENV_REQUIRED */
   306       } else {  /* do the same speculatively or exit */
   500       } else {  /* do the same speculatively or exit */
   307 #ifdef DUAL_MODE
   501 #ifdef DUAL_MODE
   308         if (running != wanted) {
   502         if (running != wanted) {
   309           /* Find out where the JRE is that we will be using. */
   503           /* Find out where the JRE is that we will be using. */
   310           if (!GetJREPath(jrepath, so_jrepath, GetArchPath(wanted), JNI_TRUE)) {
   504           if (!GetJREPath(jrepath, so_jrepath, GetArchPath(wanted), JNI_TRUE)) {
   329             exit(4);
   523             exit(4);
   330           }
   524           }
   331 
   525 
   332           /* exec child can do error checking on the existence of the path */
   526           /* exec child can do error checking on the existence of the path */
   333           jvmpathExists = GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, GetArchPath(wanted));
   527           jvmpathExists = GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath, GetArchPath(wanted));
   334 
   528 #ifdef SETENV_REQUIRED
       
   529           mustsetenv = RequiresSetenv(wanted, jvmpath);
       
   530 #endif /* SETENV_REQUIRED */
   335         }
   531         }
   336 #else
   532 #else
   337         JLI_ReportErrorMessage(JRE_ERROR2, wanted);
   533         JLI_ReportErrorMessage(JRE_ERROR2, wanted);
   338         exit(1);
   534         exit(1);
   339 #endif
   535 #endif
   340       }
   536         }
   341 
   537 #ifdef SETENV_REQUIRED
   342       {
   538         if (mustsetenv) {
   343         char *newexec = execname;
   539             /*
       
   540              * We will set the LD_LIBRARY_PATH as follows:
       
   541              *
       
   542              *     o          $JVMPATH (directory portion only)
       
   543              *     o          $JRE/lib/$LIBARCHNAME
       
   544              *     o          $JRE/../lib/$LIBARCHNAME
       
   545              *
       
   546              * followed by the user's previous effective LD_LIBRARY_PATH, if
       
   547              * any.
       
   548              */
       
   549 
       
   550 #ifdef __solaris__
       
   551             /*
       
   552              * Starting in Solaris 7, ld.so.1 supports three LD_LIBRARY_PATH
       
   553              * variables:
       
   554              *
       
   555              * 1. LD_LIBRARY_PATH -- used for 32 and 64 bit searches if
       
   556              * data-model specific variables are not set.
       
   557              *
       
   558              * 2. LD_LIBRARY_PATH_64 -- overrides and replaces LD_LIBRARY_PATH
       
   559              * for 64-bit binaries.
       
   560              *
       
   561              * 3. LD_LIBRARY_PATH_32 -- overrides and replaces LD_LIBRARY_PATH
       
   562              * for 32-bit binaries.
       
   563              *
       
   564              * The vm uses LD_LIBRARY_PATH to set the java.library.path system
       
   565              * property.  To shield the vm from the complication of multiple
       
   566              * LD_LIBRARY_PATH variables, if the appropriate data model
       
   567              * specific variable is set, we will act as if LD_LIBRARY_PATH had
       
   568              * the value of the data model specific variant and the data model
       
   569              * specific variant will be unset.  Note that the variable for the
       
   570              * *wanted* data model must be used (if it is set), not simply the
       
   571              * current running data model.
       
   572              */
       
   573 
       
   574             switch (wanted) {
       
   575                 case 0:
       
   576                     if (running == 32) {
       
   577                         dmpath = getenv("LD_LIBRARY_PATH_32");
       
   578                         wanted = 32;
       
   579                     } else {
       
   580                         dmpath = getenv("LD_LIBRARY_PATH_64");
       
   581                         wanted = 64;
       
   582                     }
       
   583                     break;
       
   584 
       
   585                 case 32:
       
   586                     dmpath = getenv("LD_LIBRARY_PATH_32");
       
   587                     break;
       
   588 
       
   589                 case 64:
       
   590                     dmpath = getenv("LD_LIBRARY_PATH_64");
       
   591                     break;
       
   592 
       
   593                 default:
       
   594                     JLI_ReportErrorMessage(JRE_ERROR3, __LINE__);
       
   595                     exit(1); /* unknown value in wanted */
       
   596                     break;
       
   597             }
       
   598 
       
   599             /*
       
   600              * If dmpath is NULL, the relevant data model specific variable is
       
   601              * not set and normal LD_LIBRARY_PATH should be used.
       
   602              */
       
   603             if (dmpath == NULL) {
       
   604                 runpath = getenv("LD_LIBRARY_PATH");
       
   605             } else {
       
   606                 runpath = dmpath;
       
   607             }
       
   608 #else
       
   609             /*
       
   610              * If not on Solaris, assume only a single LD_LIBRARY_PATH
       
   611              * variable.
       
   612              */
       
   613             runpath = getenv("LD_LIBRARY_PATH");
       
   614 #endif /* __solaris__ */
       
   615 
       
   616             /* runpath contains current effective LD_LIBRARY_PATH setting */
       
   617 
       
   618             jvmpath = JLI_StringDup(jvmpath);
       
   619             new_runpath = JLI_MemAlloc(((runpath != NULL) ? JLI_StrLen(runpath) : 0) +
       
   620                     2 * JLI_StrLen(jrepath) + 2 * JLI_StrLen(arch) +
       
   621                     JLI_StrLen(jvmpath) + 52);
       
   622             newpath = new_runpath + JLI_StrLen("LD_LIBRARY_PATH=");
       
   623 
       
   624 
       
   625             /*
       
   626              * Create desired LD_LIBRARY_PATH value for target data model.
       
   627              */
       
   628             {
       
   629                 /* remove the name of the .so from the JVM path */
       
   630                 lastslash = JLI_StrRChr(jvmpath, '/');
       
   631                 if (lastslash)
       
   632                     *lastslash = '\0';
       
   633 
       
   634                 sprintf(new_runpath, "LD_LIBRARY_PATH="
       
   635                         "%s:"
       
   636                         "%s/lib/%s:"
       
   637                         "%s/../lib/%s",
       
   638                         jvmpath,
   344 #ifdef DUAL_MODE
   639 #ifdef DUAL_MODE
   345         /*
   640                         jrepath, GetArchPath(wanted),
   346          * If the data model is being changed, the path to the
   641                         jrepath, GetArchPath(wanted)
   347          * executable must be updated accordingly; the executable name
   642 #else
   348          * and directory the executable resides in are separate.  In the
   643                         jrepath, arch,
   349          * case of 32 => 64, the new bits are assumed to reside in, e.g.
   644                         jrepath, arch
   350          * "olddir/LIBARCH64NAME/execname"; in the case of 64 => 32,
       
   351          * the bits are assumed to be in "olddir/../execname".  For example,
       
   352          *
       
   353          * olddir/sparcv9/execname
       
   354          * olddir/amd64/execname
       
   355          *
       
   356          * for Solaris SPARC and Linux amd64, respectively.
       
   357          */
       
   358 
       
   359         if (running != wanted) {
       
   360           char *oldexec = JLI_StrCpy(JLI_MemAlloc(JLI_StrLen(execname) + 1), execname);
       
   361           char *olddir = oldexec;
       
   362           char *oldbase = JLI_StrRChr(oldexec, '/');
       
   363 
       
   364 
       
   365           newexec = JLI_MemAlloc(JLI_StrLen(execname) + 20);
       
   366           *oldbase++ = 0;
       
   367           sprintf(newexec, "%s/%s/%s", olddir,
       
   368                   ((wanted==64) ? LIBARCH64NAME : ".."), oldbase);
       
   369           argv[0] = newexec;
       
   370         }
       
   371 #endif
   645 #endif
   372         JLI_TraceLauncher("TRACER_MARKER:About to EXEC\n");
   646                         );
   373         (void)fflush(stdout);
   647 
   374         (void)fflush(stderr);
   648 
   375         execv(newexec, argv);
   649                 /*
   376         JLI_ReportErrorMessageSys(JRE_ERROR4, newexec);
   650                  * Check to make sure that the prefix of the current path is the
   377 
   651                  * desired environment variable setting, though the RequiresSetenv
       
   652                  * checks if the desired runpath exists, this logic does a more
       
   653                  * comprehensive check.
       
   654                  */
       
   655                 if (runpath != NULL &&
       
   656                         JLI_StrNCmp(newpath, runpath, JLI_StrLen(newpath)) == 0 &&
       
   657                         (runpath[JLI_StrLen(newpath)] == 0 || runpath[JLI_StrLen(newpath)] == ':') &&
       
   658                         (running == wanted) /* data model does not have to be changed */
       
   659 #ifdef __solaris__
       
   660                         && (dmpath == NULL) /* data model specific variables not set  */
       
   661 #endif
       
   662                         ) {
       
   663 
       
   664                     return;
       
   665 
       
   666                 }
       
   667             }
       
   668 
       
   669             /*
       
   670              * Place the desired environment setting onto the prefix of
       
   671              * LD_LIBRARY_PATH.  Note that this prevents any possible infinite
       
   672              * loop of execv() because we test for the prefix, above.
       
   673              */
       
   674             if (runpath != 0) {
       
   675                 JLI_StrCat(new_runpath, ":");
       
   676                 JLI_StrCat(new_runpath, runpath);
       
   677             }
       
   678 
       
   679             if (putenv(new_runpath) != 0) {
       
   680                 exit(1); /* problem allocating memory; LD_LIBRARY_PATH not set
       
   681                     properly */
       
   682             }
       
   683 
       
   684             /*
       
   685              * Unix systems document that they look at LD_LIBRARY_PATH only
       
   686              * once at startup, so we have to re-exec the current executable
       
   687              * to get the changed environment variable to have an effect.
       
   688              */
       
   689 
       
   690 #ifdef __solaris__
       
   691             /*
       
   692              * If dmpath is not NULL, remove the data model specific string
       
   693              * in the environment for the exec'ed child.
       
   694              */
       
   695             if (dmpath != NULL)
       
   696                 (void)UnsetEnv((wanted == 32) ? "LD_LIBRARY_PATH_32" : "LD_LIBRARY_PATH_64");
       
   697 #endif
       
   698 
       
   699             newenvp = environ;
       
   700         }
       
   701 #endif /* SETENV_REQUIRED */
       
   702         {
       
   703             char *newexec = execname;
   378 #ifdef DUAL_MODE
   704 #ifdef DUAL_MODE
   379         if (running != wanted) {
   705             /*
   380           JLI_ReportErrorMessage(JRE_ERROR5, wanted, running);
   706              * If the data model is being changed, the path to the
   381 #  ifdef __solaris__
   707              * executable must be updated accordingly; the executable name
   382 #    ifdef __sparc
   708              * and directory the executable resides in are separate.  In the
   383           JLI_ReportErrorMessage(JRE_ERROR6);
   709              * case of 32 => 64, the new bits are assumed to reside in, e.g.
   384 #    else
   710              * "olddir/LIBARCH64NAME/execname"; in the case of 64 => 32,
   385           JLI_ReportErrorMessage(JRE_ERROR7);
   711              * the bits are assumed to be in "olddir/../execname".  For example,
   386 #    endif
   712              *
   387         }
   713              * olddir/sparcv9/execname
   388 #  endif
   714              * olddir/amd64/execname
   389 #endif
   715              *
   390 
   716              * for Solaris SPARC and Linux amd64, respectively.
   391       }
   717              */
   392       exit(1);
   718 
   393     }
   719             if (running != wanted) {
   394 
   720                 char *oldexec = JLI_StrCpy(JLI_MemAlloc(JLI_StrLen(execname) + 1), execname);
       
   721                 char *olddir = oldexec;
       
   722                 char *oldbase = JLI_StrRChr(oldexec, '/');
       
   723 
       
   724 
       
   725                 newexec = JLI_MemAlloc(JLI_StrLen(execname) + 20);
       
   726                 *oldbase++ = 0;
       
   727                 sprintf(newexec, "%s/%s/%s", olddir,
       
   728                         ((wanted == 64) ? LIBARCH64NAME : ".."), oldbase);
       
   729                 argv[0] = newexec;
       
   730             }
       
   731 #endif /* DUAL_MODE */
       
   732             JLI_TraceLauncher("TRACER_MARKER:About to EXEC\n");
       
   733             (void) fflush(stdout);
       
   734             (void) fflush(stderr);
       
   735 #ifdef SETENV_REQUIRED
       
   736             if (mustsetenv) {
       
   737                 execve(newexec, argv, newenvp);
       
   738             } else {
       
   739                 execv(newexec, argv);
       
   740             }
       
   741 #else
       
   742             execv(newexec, argv);
       
   743 #endif /* SETENV_REQUIRED */
       
   744             JLI_ReportErrorMessageSys(JRE_ERROR4, newexec);
       
   745 
       
   746 #ifdef DUAL_MODE
       
   747             if (running != wanted) {
       
   748                 JLI_ReportErrorMessage(JRE_ERROR5, wanted, running);
       
   749 #ifdef __solaris__
       
   750 #ifdef __sparc
       
   751                 JLI_ReportErrorMessage(JRE_ERROR6);
       
   752 #else
       
   753                 JLI_ReportErrorMessage(JRE_ERROR7);
       
   754 #endif  /* __sparc */
       
   755             }
       
   756 #endif /* __solaris__ */
       
   757 #endif /* DUAL_MODE */
       
   758 
       
   759         }
       
   760         exit(1);
       
   761     }
   395 }
   762 }
   396 
   763 
   397 /*
   764 /*
   398  * On Solaris VM choosing is done by the launcher (java.c).
   765  * On Solaris VM choosing is done by the launcher (java.c).
   399  */
   766  */