mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 11:34:38 +02:00
8058407: Remove Multiple JRE support in the Java launcher
Reviewed-by: alanb, darcy, ksrini
This commit is contained in:
parent
9eafb6c406
commit
918fac5a52
14 changed files with 156 additions and 1295 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -38,7 +38,6 @@
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include "manifest_info.h"
|
#include "manifest_info.h"
|
||||||
#include "version_comp.h"
|
|
||||||
|
|
||||||
/* Support Cocoa event loop on the main thread */
|
/* Support Cocoa event loop on the main thread */
|
||||||
#include <Cocoa/Cocoa.h>
|
#include <Cocoa/Cocoa.h>
|
||||||
|
@ -104,10 +103,6 @@ struct NSAppArgs {
|
||||||
* (incoming argv)
|
* (incoming argv)
|
||||||
* |
|
* |
|
||||||
* \|/
|
* \|/
|
||||||
* SelectVersion
|
|
||||||
* (selects the JRE version, note: not data model)
|
|
||||||
* |
|
|
||||||
* \|/
|
|
||||||
* CreateExecutionEnvironment
|
* CreateExecutionEnvironment
|
||||||
* (determines desired data model)
|
* (determines desired data model)
|
||||||
* |
|
* |
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -72,9 +72,6 @@
|
||||||
#define CFG_ERROR8 "Error: missing `%s' JVM at `%s'.\nPlease install or use the JRE or JDK that contains these missing components."
|
#define CFG_ERROR8 "Error: missing `%s' JVM at `%s'.\nPlease install or use the JRE or JDK that contains these missing components."
|
||||||
#define CFG_ERROR9 "Error: could not determine JVM type."
|
#define CFG_ERROR9 "Error: could not determine JVM type."
|
||||||
|
|
||||||
|
|
||||||
#define SPC_ERROR1 "Error: Syntax error in version specification \"%s\""
|
|
||||||
|
|
||||||
#define JRE_ERROR1 "Error: Could not find Java SE Runtime Environment."
|
#define JRE_ERROR1 "Error: Could not find Java SE Runtime Environment."
|
||||||
#define JRE_ERROR2 "Error: This Java instance does not support a %d-bit JVM.\nPlease install the desired version."
|
#define JRE_ERROR2 "Error: This Java instance does not support a %d-bit JVM.\nPlease install the desired version."
|
||||||
#define JRE_ERROR3 "Error: Improper value at line %d."
|
#define JRE_ERROR3 "Error: Improper value at line %d."
|
||||||
|
@ -89,6 +86,9 @@
|
||||||
#define JRE_ERROR12 "Error: Exec of %s failed"
|
#define JRE_ERROR12 "Error: Exec of %s failed"
|
||||||
#define JRE_ERROR13 "Error: String processing operation failed"
|
#define JRE_ERROR13 "Error: String processing operation failed"
|
||||||
|
|
||||||
|
#define SPC_ERROR1 "Error: Specifying an alternate JDK/JRE version is no longer supported.\n The use of the flag '-version:' is no longer valid.\n Please download and execute the appropriate version."
|
||||||
|
#define SPC_ERROR2 "Error: Specifying an alternate JDK/JRE is no longer supported.\n The related flags -jre-restrict-search | -jre-no-restrict-search are also no longer valid."
|
||||||
|
|
||||||
#define DLL_ERROR1 "Error: dl failure on line %d"
|
#define DLL_ERROR1 "Error: dl failure on line %d"
|
||||||
#define DLL_ERROR2 "Error: failed %s, because %s"
|
#define DLL_ERROR2 "Error: failed %s, because %s"
|
||||||
#define DLL_ERROR3 "Error: could not find executable %s"
|
#define DLL_ERROR3 "Error: could not find executable %s"
|
||||||
|
|
|
@ -216,21 +216,14 @@ JLI_Launch(int argc, char ** argv, /* main argc, argc */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure the specified version of the JRE is running.
|
* SelectVersion() has several responsibilities:
|
||||||
*
|
*
|
||||||
* There are three things to note about the SelectVersion() routine:
|
* 1) Disallow specification of another JRE. With 1.9, another
|
||||||
* 1) If the version running isn't correct, this routine doesn't
|
* version of the JRE cannot be invoked.
|
||||||
* return (either the correct version has been exec'd or an error
|
* 2) Allow for a JRE version to invoke JDK 1.9 or later. Since
|
||||||
* was issued).
|
* all mJRE directives have been stripped from the request but
|
||||||
* 2) Argc and Argv in this scope are *not* altered by this routine.
|
* the pre 1.9 JRE [ 1.6 thru 1.8 ], it is as if 1.9+ has been
|
||||||
* It is the responsibility of subsequent code to ignore the
|
* invoked from the command line.
|
||||||
* arguments handled by this routine.
|
|
||||||
* 3) As a side-effect, the variable "main_class" is guaranteed to
|
|
||||||
* be set (if it should ever be set). This isn't exactly the
|
|
||||||
* poster child for structured programming, but it is a small
|
|
||||||
* price to pay for not processing a jar file operand twice.
|
|
||||||
* (Note: This side effect has been disabled. See comment on
|
|
||||||
* bugid 5030265 below.)
|
|
||||||
*/
|
*/
|
||||||
SelectVersion(argc, argv, &main_class);
|
SelectVersion(argc, argv, &main_class);
|
||||||
|
|
||||||
|
@ -829,8 +822,6 @@ static void
|
||||||
SelectVersion(int argc, char **argv, char **main_class)
|
SelectVersion(int argc, char **argv, char **main_class)
|
||||||
{
|
{
|
||||||
char *arg;
|
char *arg;
|
||||||
char **new_argv;
|
|
||||||
char **new_argp;
|
|
||||||
char *operand;
|
char *operand;
|
||||||
char *version = NULL;
|
char *version = NULL;
|
||||||
char *jre = NULL;
|
char *jre = NULL;
|
||||||
|
@ -849,6 +840,17 @@ SelectVersion(int argc, char **argv, char **main_class)
|
||||||
* with the value passed through the environment (if any) and
|
* with the value passed through the environment (if any) and
|
||||||
* simply return.
|
* simply return.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This environmental variable can be set by mJRE capable JREs
|
||||||
|
* [ 1.5 thru 1.8 ]. All other aspects of mJRE processing have been
|
||||||
|
* stripped by those JREs. This environmental variable allows 1.9+
|
||||||
|
* JREs to be started by these mJRE capable JREs.
|
||||||
|
* Note that mJRE directives in the jar manifest file would have been
|
||||||
|
* ignored for a JRE started by another JRE...
|
||||||
|
* .. skipped for JRE 1.5 and beyond.
|
||||||
|
* .. not even checked for pre 1.5.
|
||||||
|
*/
|
||||||
if ((env_in = getenv(ENV_ENTRY)) != NULL) {
|
if ((env_in = getenv(ENV_ENTRY)) != NULL) {
|
||||||
if (*env_in != '\0')
|
if (*env_in != '\0')
|
||||||
*main_class = JLI_StringDup(env_in);
|
*main_class = JLI_StringDup(env_in);
|
||||||
|
@ -857,41 +859,26 @@ SelectVersion(int argc, char **argv, char **main_class)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scan through the arguments for options relevant to multiple JRE
|
* Scan through the arguments for options relevant to multiple JRE
|
||||||
* support. For reference, the command line syntax is defined as:
|
* support. Multiple JRE support existed in JRE versions 1.5 thru 1.8.
|
||||||
*
|
*
|
||||||
* SYNOPSIS
|
* This capability is no longer available with JRE versions 1.9 and later.
|
||||||
* java [options] class [argument...]
|
* These command line options are reported as errors.
|
||||||
*
|
|
||||||
* java [options] -jar file.jar [argument...]
|
|
||||||
*
|
|
||||||
* As the scan is performed, make a copy of the argument list with
|
|
||||||
* the version specification options (new to 1.5) removed, so that
|
|
||||||
* a version less than 1.5 can be exec'd.
|
|
||||||
*
|
|
||||||
* Note that due to the syntax of the native Windows interface
|
|
||||||
* CreateProcess(), processing similar to the following exists in
|
|
||||||
* the Windows platform specific routine ExecJRE (in java_md.c).
|
|
||||||
* Changes here should be reproduced there.
|
|
||||||
*/
|
*/
|
||||||
new_argv = JLI_MemAlloc((argc + 1) * sizeof(char*));
|
|
||||||
new_argv[0] = argv[0];
|
|
||||||
new_argp = &new_argv[1];
|
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
while ((arg = *argv) != 0 && *arg == '-') {
|
while ((arg = *argv) != 0 && *arg == '-') {
|
||||||
if (JLI_StrCCmp(arg, "-version:") == 0) {
|
if (JLI_StrCCmp(arg, "-version:") == 0) {
|
||||||
version = arg + 9;
|
JLI_ReportErrorMessage(SPC_ERROR1);
|
||||||
} else if (JLI_StrCmp(arg, "-jre-restrict-search") == 0) {
|
} else if (JLI_StrCmp(arg, "-jre-restrict-search") == 0) {
|
||||||
restrict_search = 1;
|
JLI_ReportErrorMessage(SPC_ERROR2);
|
||||||
} else if (JLI_StrCmp(arg, "-no-jre-restrict-search") == 0) {
|
} else if (JLI_StrCmp(arg, "-jre-no-restrict-search") == 0) {
|
||||||
restrict_search = 0;
|
JLI_ReportErrorMessage(SPC_ERROR2);
|
||||||
} else {
|
} else {
|
||||||
if (JLI_StrCmp(arg, "-jar") == 0)
|
if (JLI_StrCmp(arg, "-jar") == 0)
|
||||||
jarflag = 1;
|
jarflag = 1;
|
||||||
/* deal with "unfortunate" classpath syntax */
|
/* deal with "unfortunate" classpath syntax */
|
||||||
if ((JLI_StrCmp(arg, "-classpath") == 0 || JLI_StrCmp(arg, "-cp") == 0) &&
|
if ((JLI_StrCmp(arg, "-classpath") == 0 || JLI_StrCmp(arg, "-cp") == 0) &&
|
||||||
(argc >= 2)) {
|
(argc >= 2)) {
|
||||||
*new_argp++ = arg;
|
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
arg = *argv;
|
arg = *argv;
|
||||||
|
@ -908,7 +895,6 @@ SelectVersion(int argc, char **argv, char **main_class)
|
||||||
} else if (JLI_StrCCmp(arg, "-splash:") == 0) {
|
} else if (JLI_StrCCmp(arg, "-splash:") == 0) {
|
||||||
splash_file_name = arg+8;
|
splash_file_name = arg+8;
|
||||||
}
|
}
|
||||||
*new_argp++ = arg;
|
|
||||||
}
|
}
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
|
@ -917,11 +903,8 @@ SelectVersion(int argc, char **argv, char **main_class)
|
||||||
operand = NULL;
|
operand = NULL;
|
||||||
} else {
|
} else {
|
||||||
argc--;
|
argc--;
|
||||||
*new_argp++ = operand = *argv++;
|
operand = *argv++;
|
||||||
}
|
}
|
||||||
while (argc-- > 0) /* Copy over [argument...] */
|
|
||||||
*new_argp++ = *argv++;
|
|
||||||
*new_argp = NULL;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there is a jar file, read the manifest. If the jarfile can't be
|
* If there is a jar file, read the manifest. If the jarfile can't be
|
||||||
|
@ -974,14 +957,6 @@ SelectVersion(int argc, char **argv, char **main_class)
|
||||||
putenv(splash_jar_entry);
|
putenv(splash_jar_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The JRE-Version and JRE-Restrict-Search values (if any) from the
|
|
||||||
* manifest are overwritten by any specified on the command line.
|
|
||||||
*/
|
|
||||||
if (version != NULL)
|
|
||||||
info.jre_version = version;
|
|
||||||
if (restrict_search != -1)
|
|
||||||
info.jre_restrict_search = restrict_search;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "Valid" returns (other than unrecoverable errors) follow. Set
|
* "Valid" returns (other than unrecoverable errors) follow. Set
|
||||||
|
@ -990,72 +965,11 @@ SelectVersion(int argc, char **argv, char **main_class)
|
||||||
if (info.main_class != NULL)
|
if (info.main_class != NULL)
|
||||||
*main_class = JLI_StringDup(info.main_class);
|
*main_class = JLI_StringDup(info.main_class);
|
||||||
|
|
||||||
/*
|
|
||||||
* If no version selection information is found either on the command
|
|
||||||
* line or in the manifest, simply return.
|
|
||||||
*/
|
|
||||||
if (info.jre_version == NULL) {
|
if (info.jre_version == NULL) {
|
||||||
JLI_FreeManifest();
|
JLI_FreeManifest();
|
||||||
JLI_MemFree(new_argv);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Check for correct syntax of the version specification (JSR 56).
|
|
||||||
*/
|
|
||||||
if (!JLI_ValidVersionString(info.jre_version)) {
|
|
||||||
JLI_ReportErrorMessage(SPC_ERROR1, info.jre_version);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find the appropriate JVM on the system. Just to be as forgiving as
|
|
||||||
* possible, if the standard algorithms don't locate an appropriate
|
|
||||||
* jre, check to see if the one running will satisfy the requirements.
|
|
||||||
* This can happen on systems which haven't been set-up for multiple
|
|
||||||
* JRE support.
|
|
||||||
*/
|
|
||||||
jre = LocateJRE(&info);
|
|
||||||
JLI_TraceLauncher("JRE-Version = %s, JRE-Restrict-Search = %s Selected = %s\n",
|
|
||||||
(info.jre_version?info.jre_version:"null"),
|
|
||||||
(info.jre_restrict_search?"true":"false"), (jre?jre:"null"));
|
|
||||||
|
|
||||||
if (jre == NULL) {
|
|
||||||
if (JLI_AcceptableRelease(GetFullVersion(), info.jre_version)) {
|
|
||||||
JLI_FreeManifest();
|
|
||||||
JLI_MemFree(new_argv);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
JLI_ReportErrorMessage(CFG_ERROR4, info.jre_version);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If I'm not the chosen one, exec the chosen one. Returning from
|
|
||||||
* ExecJRE indicates that I am indeed the chosen one.
|
|
||||||
*
|
|
||||||
* The private environment variable _JAVA_VERSION_SET is used to
|
|
||||||
* prevent the chosen one from re-reading the manifest file and
|
|
||||||
* using the values found within to override the (potential) command
|
|
||||||
* line flags stripped from argv (because the target may not
|
|
||||||
* understand them). Passing the MainClass value is an optimization
|
|
||||||
* to avoid locating, expanding and parsing the manifest extra
|
|
||||||
* times.
|
|
||||||
*/
|
|
||||||
if (info.main_class != NULL) {
|
|
||||||
if (JLI_StrLen(info.main_class) <= MAXNAMELEN) {
|
|
||||||
(void)JLI_StrCat(env_entry, info.main_class);
|
|
||||||
} else {
|
|
||||||
JLI_ReportErrorMessage(CLS_ERROR5, MAXNAMELEN);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(void)putenv(env_entry);
|
|
||||||
ExecJRE(jre, new_argv);
|
|
||||||
JLI_FreeManifest();
|
|
||||||
JLI_MemFree(new_argv);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1154,10 +1068,7 @@ ParseArguments(int *pargc, char ***pargv,
|
||||||
JLI_StrCmp(arg, "-noasyncgc") == 0) {
|
JLI_StrCmp(arg, "-noasyncgc") == 0) {
|
||||||
/* No longer supported */
|
/* No longer supported */
|
||||||
JLI_ReportErrorMessage(ARG_WARN, arg);
|
JLI_ReportErrorMessage(ARG_WARN, arg);
|
||||||
} else if (JLI_StrCCmp(arg, "-version:") == 0 ||
|
} else if (JLI_StrCCmp(arg, "-splash:") == 0) {
|
||||||
JLI_StrCmp(arg, "-no-jre-restrict-search") == 0 ||
|
|
||||||
JLI_StrCmp(arg, "-jre-restrict-search") == 0 ||
|
|
||||||
JLI_StrCCmp(arg, "-splash:") == 0) {
|
|
||||||
; /* Ignore machine independent options already handled */
|
; /* Ignore machine independent options already handled */
|
||||||
} else if (ProcessPlatformOption(arg)) {
|
} else if (ProcessPlatformOption(arg)) {
|
||||||
; /* Processing of platform dependent options */
|
; /* Processing of platform dependent options */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -40,9 +40,7 @@
|
||||||
#include "emessages.h"
|
#include "emessages.h"
|
||||||
#include "java_md.h"
|
#include "java_md.h"
|
||||||
#include "jli_util.h"
|
#include "jli_util.h"
|
||||||
|
|
||||||
#include "manifest_info.h"
|
#include "manifest_info.h"
|
||||||
#include "version_comp.h"
|
|
||||||
#include "wildcard.h"
|
#include "wildcard.h"
|
||||||
#include "splashscreen.h"
|
#include "splashscreen.h"
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -588,15 +588,16 @@ JLI_ParseManifest(char *jarfile, manifest_info *info)
|
||||||
}
|
}
|
||||||
lp = manifest;
|
lp = manifest;
|
||||||
while ((rc = parse_nv_pair(&lp, &name, &value)) > 0) {
|
while ((rc = parse_nv_pair(&lp, &name, &value)) > 0) {
|
||||||
if (JLI_StrCaseCmp(name, "Manifest-Version") == 0)
|
if (JLI_StrCaseCmp(name, "Manifest-Version") == 0) {
|
||||||
info->manifest_version = value;
|
info->manifest_version = value;
|
||||||
else if (JLI_StrCaseCmp(name, "Main-Class") == 0)
|
} else if (JLI_StrCaseCmp(name, "Main-Class") == 0) {
|
||||||
info->main_class = value;
|
info->main_class = value;
|
||||||
else if (JLI_StrCaseCmp(name, "JRE-Version") == 0)
|
} else if (JLI_StrCaseCmp(name, "JRE-Version") == 0) {
|
||||||
info->jre_version = value;
|
/*
|
||||||
else if (JLI_StrCaseCmp(name, "JRE-Restrict-Search") == 0) {
|
* Manifest specification overridden by command line option
|
||||||
if (JLI_StrCaseCmp(value, "true") == 0)
|
* so we will silently override there with no specification.
|
||||||
info->jre_restrict_search = 1;
|
*/
|
||||||
|
info->jre_version = 0;
|
||||||
} else if (JLI_StrCaseCmp(name, "Splashscreen-Image") == 0) {
|
} else if (JLI_StrCaseCmp(name, "Splashscreen-Image") == 0) {
|
||||||
info->splashscreen_image_file_name = value;
|
info->splashscreen_image_file_name = value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,357 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include "jni.h"
|
|
||||||
#include "jli_util.h"
|
|
||||||
#include "version_comp.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A collection of useful strings. One should think of these as #define
|
|
||||||
* entries, but actual strings can be more efficient (with many compilers).
|
|
||||||
*/
|
|
||||||
static const char *separators = ".-_";
|
|
||||||
static const char *zero_string = "0";
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Validate a string as parsable as a "Java int". If so parsable,
|
|
||||||
* return true (non-zero) and store the numeric value at the address
|
|
||||||
* passed in as "value"; otherwise return false (zero).
|
|
||||||
*
|
|
||||||
* Note that the maximum allowable value is 2147483647 as defined by
|
|
||||||
* the "Java Language Specification" which precludes the use of native
|
|
||||||
* conversion routines which may have other limits.
|
|
||||||
*
|
|
||||||
* Also note that we don't have to worry about the alternate maximum
|
|
||||||
* allowable value of 2147483648 because it is only allowed after
|
|
||||||
* the unary negation operator and this grammar doesn't have one
|
|
||||||
* of those.
|
|
||||||
*
|
|
||||||
* Finally, note that a value which exceeds the maximum jint value will
|
|
||||||
* return false (zero). This results in the otherwise purely numeric
|
|
||||||
* string being compared as a string of characters (as per the spec.)
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
isjavaint(const char *s, jint *value)
|
|
||||||
{
|
|
||||||
jlong sum = 0;
|
|
||||||
jint digit;
|
|
||||||
while (*s != '\0')
|
|
||||||
if (isdigit(*s)) {
|
|
||||||
digit = (jint)((int)(*s++) - (int)('0'));
|
|
||||||
sum = (sum * 10) + digit;
|
|
||||||
if (sum > 2147483647)
|
|
||||||
return (0); /* Overflows jint (but not jlong) */
|
|
||||||
} else
|
|
||||||
return (0);
|
|
||||||
*value = (jint)sum;
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Modeled after strcmp(), compare two strings (as in the grammar defined
|
|
||||||
* in Appendix A of JSR 56). If both strings can be interpreted as
|
|
||||||
* Java ints, do a numeric comparison, else it is strcmp().
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
comp_string(const char *s1, const char *s2)
|
|
||||||
{
|
|
||||||
jint v1, v2;
|
|
||||||
if (isjavaint(s1, &v1) && isjavaint(s2, &v2))
|
|
||||||
return ((int)(v1 - v2));
|
|
||||||
else
|
|
||||||
return (JLI_StrCmp(s1, s2));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Modeled after strcmp(), compare two version-ids for a Prefix
|
|
||||||
* Match as defined in JSR 56.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
JLI_PrefixVersionId(const char *id1, char *id2)
|
|
||||||
{
|
|
||||||
char *s1 = JLI_StringDup(id1);
|
|
||||||
char *s2 = JLI_StringDup(id2);
|
|
||||||
char *m1 = s1;
|
|
||||||
char *m2 = s2;
|
|
||||||
char *end1 = NULL;
|
|
||||||
char *end2 = NULL;
|
|
||||||
int res = 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
|
|
||||||
if ((s1 != NULL) && ((end1 = JLI_StrPBrk(s1, ".-_")) != NULL))
|
|
||||||
*end1 = '\0';
|
|
||||||
if ((s2 != NULL) && ((end2 = JLI_StrPBrk(s2, ".-_")) != NULL))
|
|
||||||
*end2 = '\0';
|
|
||||||
|
|
||||||
res = comp_string(s1, s2);
|
|
||||||
|
|
||||||
if (end1 != NULL)
|
|
||||||
s1 = end1 + 1;
|
|
||||||
else
|
|
||||||
s1 = NULL;
|
|
||||||
if (end2 != NULL)
|
|
||||||
s2 = end2 + 1;
|
|
||||||
else
|
|
||||||
s2 = NULL;
|
|
||||||
|
|
||||||
} while (res == 0 && ((s1 != NULL) && (s2 != NULL)));
|
|
||||||
|
|
||||||
JLI_MemFree(m1);
|
|
||||||
JLI_MemFree(m2);
|
|
||||||
return (res);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Modeled after strcmp(), compare two version-ids for an Exact
|
|
||||||
* Match as defined in JSR 56.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
JLI_ExactVersionId(const char *id1, char *id2)
|
|
||||||
{
|
|
||||||
char *s1 = JLI_StringDup(id1);
|
|
||||||
char *s2 = JLI_StringDup(id2);
|
|
||||||
char *m1 = s1;
|
|
||||||
char *m2 = s2;
|
|
||||||
char *end1 = NULL;
|
|
||||||
char *end2 = NULL;
|
|
||||||
int res = 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
|
|
||||||
if ((s1 != NULL) && ((end1 = JLI_StrPBrk(s1, separators)) != NULL))
|
|
||||||
*end1 = '\0';
|
|
||||||
if ((s2 != NULL) && ((end2 = JLI_StrPBrk(s2, separators)) != NULL))
|
|
||||||
*end2 = '\0';
|
|
||||||
|
|
||||||
if ((s1 != NULL) && (s2 == NULL))
|
|
||||||
res = comp_string(s1, zero_string);
|
|
||||||
else if ((s1 == NULL) && (s2 != NULL))
|
|
||||||
res = comp_string(zero_string, s2);
|
|
||||||
else
|
|
||||||
res = comp_string(s1, s2);
|
|
||||||
|
|
||||||
if (end1 != NULL)
|
|
||||||
s1 = end1 + 1;
|
|
||||||
else
|
|
||||||
s1 = NULL;
|
|
||||||
if (end2 != NULL)
|
|
||||||
s2 = end2 + 1;
|
|
||||||
else
|
|
||||||
s2 = NULL;
|
|
||||||
|
|
||||||
} while (res == 0 && ((s1 != NULL) || (s2 != NULL)));
|
|
||||||
|
|
||||||
JLI_MemFree(m1);
|
|
||||||
JLI_MemFree(m2);
|
|
||||||
return (res);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return true if this simple-element (as defined in JSR 56) forms
|
|
||||||
* an acceptable match.
|
|
||||||
*
|
|
||||||
* JSR 56 is modified by the Java Web Start <rel> Developer Guide
|
|
||||||
* where it is stated "... Java Web Start will not consider an installed
|
|
||||||
* non-FCS (i.e., milestone) JRE as a match. ... a JRE from Sun
|
|
||||||
* Microsystems, Inc., is by convention a non-FCS (milestone) JRE
|
|
||||||
* if there is a dash (-) in the version string."
|
|
||||||
*
|
|
||||||
* An undocumented caveat to the above is that an exact match with a
|
|
||||||
* hyphen is accepted as a development extension.
|
|
||||||
*
|
|
||||||
* These modifications are addressed by the specific comparisons
|
|
||||||
* for releases with hyphens.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
acceptable_simple_element(const char *release, char *simple_element)
|
|
||||||
{
|
|
||||||
char *modifier;
|
|
||||||
modifier = simple_element + JLI_StrLen(simple_element) - 1;
|
|
||||||
if (*modifier == '*') {
|
|
||||||
*modifier = '\0';
|
|
||||||
if (JLI_StrChr(release, '-'))
|
|
||||||
return ((JLI_StrCmp(release, simple_element) == 0)?1:0);
|
|
||||||
return ((JLI_PrefixVersionId(release, simple_element) == 0)?1:0);
|
|
||||||
} else if (*modifier == '+') {
|
|
||||||
*modifier = '\0';
|
|
||||||
if (JLI_StrChr(release, '-'))
|
|
||||||
return ((JLI_StrCmp(release, simple_element) == 0)?1:0);
|
|
||||||
return ((JLI_ExactVersionId(release, simple_element) >= 0)?1:0);
|
|
||||||
} else {
|
|
||||||
return ((JLI_ExactVersionId(release, simple_element) == 0)?1:0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return true if this element (as defined in JSR 56) forms
|
|
||||||
* an acceptable match. An element is the intersection (and)
|
|
||||||
* of multiple simple-elements.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
acceptable_element(const char *release, char *element)
|
|
||||||
{
|
|
||||||
char *end;
|
|
||||||
do {
|
|
||||||
if ((end = JLI_StrChr(element, '&')) != NULL)
|
|
||||||
*end = '\0';
|
|
||||||
if (!acceptable_simple_element(release, element))
|
|
||||||
return (0);
|
|
||||||
if (end != NULL)
|
|
||||||
element = end + 1;
|
|
||||||
} while (end != NULL);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Checks if release is acceptable by the specification version-string.
|
|
||||||
* Return true if this version-string (as defined in JSR 56) forms
|
|
||||||
* an acceptable match. A version-string is the union (or) of multiple
|
|
||||||
* elements.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
JLI_AcceptableRelease(const char *release, char *version_string)
|
|
||||||
{
|
|
||||||
char *vs;
|
|
||||||
char *m1;
|
|
||||||
char *end;
|
|
||||||
m1 = vs = JLI_StringDup(version_string);
|
|
||||||
do {
|
|
||||||
if ((end = JLI_StrChr(vs, ' ')) != NULL)
|
|
||||||
*end = '\0';
|
|
||||||
if (acceptable_element(release, vs)) {
|
|
||||||
JLI_MemFree(m1);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
if (end != NULL)
|
|
||||||
vs = end + 1;
|
|
||||||
} while (end != NULL);
|
|
||||||
JLI_MemFree(m1);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return true if this is a valid simple-element (as defined in JSR 56).
|
|
||||||
*
|
|
||||||
* The official grammar for a simple-element is:
|
|
||||||
*
|
|
||||||
* simple-element ::= version-id | version-id modifier
|
|
||||||
* modifier ::= '+' | '*'
|
|
||||||
* version-id ::= string ( separator string )*
|
|
||||||
* string ::= char ( char )*
|
|
||||||
* char ::= Any ASCII character except a space, an
|
|
||||||
* ampersand, a separator or a modifier
|
|
||||||
* separator ::= '.' | '-' | '_'
|
|
||||||
*
|
|
||||||
* However, for efficiency, it is time to abandon the top down parser
|
|
||||||
* implementation. After deleting the potential trailing modifier, we
|
|
||||||
* are left with a version-id.
|
|
||||||
*
|
|
||||||
* Note that a valid version-id has three simple properties:
|
|
||||||
*
|
|
||||||
* 1) Doesn't contain a space, an ampersand or a modifier.
|
|
||||||
*
|
|
||||||
* 2) Doesn't begin or end with a separator.
|
|
||||||
*
|
|
||||||
* 3) Doesn't contain two adjacent separators.
|
|
||||||
*
|
|
||||||
* Any other line noise constitutes a valid version-id.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
valid_simple_element(char *simple_element)
|
|
||||||
{
|
|
||||||
char *last;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
if ((simple_element == NULL) || ((len = JLI_StrLen(simple_element)) == 0))
|
|
||||||
return (0);
|
|
||||||
last = simple_element + len - 1;
|
|
||||||
if (*last == '*' || *last == '+') {
|
|
||||||
if (--len == 0)
|
|
||||||
return (0);
|
|
||||||
*last-- = '\0';
|
|
||||||
}
|
|
||||||
if (JLI_StrPBrk(simple_element, " &+*") != NULL) /* Property #1 */
|
|
||||||
return (0);
|
|
||||||
if ((JLI_StrChr(".-_", *simple_element) != NULL) || /* Property #2 */
|
|
||||||
(JLI_StrChr(".-_", *last) != NULL))
|
|
||||||
return (0);
|
|
||||||
for (; simple_element != last; simple_element++) /* Property #3 */
|
|
||||||
if ((JLI_StrChr(".-_", *simple_element) != NULL) &&
|
|
||||||
(JLI_StrChr(".-_", *(simple_element + 1)) != NULL))
|
|
||||||
return (0);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return true if this is a valid element (as defined in JSR 56).
|
|
||||||
* An element is the intersection (and) of multiple simple-elements.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
valid_element(char *element)
|
|
||||||
{
|
|
||||||
char *end;
|
|
||||||
if ((element == NULL) || (JLI_StrLen(element) == 0))
|
|
||||||
return (0);
|
|
||||||
do {
|
|
||||||
if ((end = JLI_StrChr(element, '&')) != NULL)
|
|
||||||
*end = '\0';
|
|
||||||
if (!valid_simple_element(element))
|
|
||||||
return (0);
|
|
||||||
if (end != NULL)
|
|
||||||
element = end + 1;
|
|
||||||
} while (end != NULL);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Validates a version string by the extended JSR 56 grammar.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
JLI_ValidVersionString(char *version_string)
|
|
||||||
{
|
|
||||||
char *vs;
|
|
||||||
char *m1;
|
|
||||||
char *end;
|
|
||||||
if ((version_string == NULL) || (JLI_StrLen(version_string) == 0))
|
|
||||||
return (0);
|
|
||||||
m1 = vs = JLI_StringDup(version_string);
|
|
||||||
do {
|
|
||||||
if ((end = JLI_StrChr(vs, ' ')) != NULL)
|
|
||||||
*end = '\0';
|
|
||||||
if (!valid_element(vs)) {
|
|
||||||
JLI_MemFree(m1);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
if (end != NULL)
|
|
||||||
vs = end + 1;
|
|
||||||
} while (end != NULL);
|
|
||||||
JLI_MemFree(m1);
|
|
||||||
return (1);
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
||||||
*
|
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
|
||||||
* published by the Free Software Foundation. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
||||||
* or visit www.oracle.com if you need additional information or have any
|
|
||||||
* questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _VERSION_COMP_H
|
|
||||||
#define _VERSION_COMP_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function prototypes.
|
|
||||||
*/
|
|
||||||
int JLI_ExactVersionId(const char *id1, char *id2);
|
|
||||||
int JLI_PrefixVersionId(const char *id1, char *id2);
|
|
||||||
int JLI_AcceptableRelease(const char *release, char *version_string);
|
|
||||||
int JLI_ValidVersionString(char *version_string);
|
|
||||||
|
|
||||||
#endif /* _VERSION_COMP_H */
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -43,11 +43,6 @@
|
||||||
#define MAXNAMELEN PATH_MAX
|
#define MAXNAMELEN PATH_MAX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* Common function prototypes and sundries.
|
|
||||||
*/
|
|
||||||
char *LocateJRE(manifest_info *info);
|
|
||||||
void ExecJRE(char *jre, char **argv);
|
|
||||||
int UnsetEnv(char *name);
|
int UnsetEnv(char *name);
|
||||||
char *FindExecName(char *program);
|
char *FindExecName(char *program);
|
||||||
const char *SetExecname(char **argv);
|
const char *SetExecname(char **argv);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -190,200 +190,6 @@ CheckSanity(char *path, char *dir)
|
||||||
return ((access(buffer, X_OK) == 0) ? 1 : 0);
|
return ((access(buffer, X_OK) == 0) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Determine if there is an acceptable JRE in the directory dirname.
|
|
||||||
* Upon locating the "best" one, return a fully qualified path to
|
|
||||||
* it. "Best" is defined as the most advanced JRE meeting the
|
|
||||||
* constraints contained in the manifest_info. If no JRE in this
|
|
||||||
* directory meets the constraints, return NULL.
|
|
||||||
*
|
|
||||||
* Note that we don't check for errors in reading the directory
|
|
||||||
* (which would be done by checking errno). This is because it
|
|
||||||
* doesn't matter if we get an error reading the directory, or
|
|
||||||
* we just don't find anything interesting in the directory. We
|
|
||||||
* just return NULL in either case.
|
|
||||||
*
|
|
||||||
* The historical names of j2sdk and j2re were changed to jdk and
|
|
||||||
* jre respecively as part of the 1.5 rebranding effort. Since the
|
|
||||||
* former names are legacy on Linux, they must be recognized for
|
|
||||||
* all time. Fortunately, this is a minor cost.
|
|
||||||
*/
|
|
||||||
static char
|
|
||||||
*ProcessDir(manifest_info *info, char *dirname)
|
|
||||||
{
|
|
||||||
DIR *dirp;
|
|
||||||
struct dirent *dp;
|
|
||||||
char *best = NULL;
|
|
||||||
int offset;
|
|
||||||
int best_offset = 0;
|
|
||||||
char *ret_str = NULL;
|
|
||||||
char buffer[PATH_MAX];
|
|
||||||
|
|
||||||
if ((dirp = opendir(dirname)) == NULL)
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
do {
|
|
||||||
if ((dp = readdir(dirp)) != NULL) {
|
|
||||||
offset = 0;
|
|
||||||
if ((JLI_StrNCmp(dp->d_name, "jre", 3) == 0) ||
|
|
||||||
(JLI_StrNCmp(dp->d_name, "jdk", 3) == 0))
|
|
||||||
offset = 3;
|
|
||||||
else if (JLI_StrNCmp(dp->d_name, "j2re", 4) == 0)
|
|
||||||
offset = 4;
|
|
||||||
else if (JLI_StrNCmp(dp->d_name, "j2sdk", 5) == 0)
|
|
||||||
offset = 5;
|
|
||||||
if (offset > 0) {
|
|
||||||
if ((JLI_AcceptableRelease(dp->d_name + offset,
|
|
||||||
info->jre_version)) && CheckSanity(dirname, dp->d_name))
|
|
||||||
if ((best == NULL) || (JLI_ExactVersionId(
|
|
||||||
dp->d_name + offset, best + best_offset) > 0)) {
|
|
||||||
if (best != NULL)
|
|
||||||
JLI_MemFree(best);
|
|
||||||
best = JLI_StringDup(dp->d_name);
|
|
||||||
best_offset = offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (dp != NULL);
|
|
||||||
(void) closedir(dirp);
|
|
||||||
if (best == NULL)
|
|
||||||
return (NULL);
|
|
||||||
else {
|
|
||||||
ret_str = JLI_MemAlloc(JLI_StrLen(dirname) + JLI_StrLen(best) + 2);
|
|
||||||
sprintf(ret_str, "%s/%s", dirname, best);
|
|
||||||
JLI_MemFree(best);
|
|
||||||
return (ret_str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is the global entry point. It examines the host for the optimal
|
|
||||||
* JRE to be used by scanning a set of directories. The set of directories
|
|
||||||
* is platform dependent and can be overridden by the environment
|
|
||||||
* variable JAVA_VERSION_PATH.
|
|
||||||
*
|
|
||||||
* This routine itself simply determines the set of appropriate
|
|
||||||
* directories before passing control onto ProcessDir().
|
|
||||||
*/
|
|
||||||
char*
|
|
||||||
LocateJRE(manifest_info* info)
|
|
||||||
{
|
|
||||||
char *path;
|
|
||||||
char *home;
|
|
||||||
char *target = NULL;
|
|
||||||
char *dp;
|
|
||||||
char *cp;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Start by getting JAVA_VERSION_PATH
|
|
||||||
*/
|
|
||||||
if (info->jre_restrict_search) {
|
|
||||||
path = JLI_StringDup(system_dir);
|
|
||||||
} else if ((path = getenv("JAVA_VERSION_PATH")) != NULL) {
|
|
||||||
path = JLI_StringDup(path);
|
|
||||||
} else {
|
|
||||||
if ((home = getenv("HOME")) != NULL) {
|
|
||||||
path = (char *)JLI_MemAlloc(JLI_StrLen(home) + \
|
|
||||||
JLI_StrLen(system_dir) + JLI_StrLen(user_dir) + 2);
|
|
||||||
sprintf(path, "%s%s:%s", home, user_dir, system_dir);
|
|
||||||
} else {
|
|
||||||
path = JLI_StringDup(system_dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Step through each directory on the path. Terminate the scan with
|
|
||||||
* the first directory with an acceptable JRE.
|
|
||||||
*/
|
|
||||||
cp = dp = path;
|
|
||||||
while (dp != NULL) {
|
|
||||||
cp = JLI_StrChr(dp, (int)':');
|
|
||||||
if (cp != NULL)
|
|
||||||
*cp = '\0';
|
|
||||||
if ((target = ProcessDir(info, dp)) != NULL)
|
|
||||||
break;
|
|
||||||
dp = cp;
|
|
||||||
if (dp != NULL)
|
|
||||||
dp++;
|
|
||||||
}
|
|
||||||
JLI_MemFree(path);
|
|
||||||
return (target);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Given a path to a jre to execute, this routine checks if this process
|
|
||||||
* is indeed that jre. If not, it exec's that jre.
|
|
||||||
*
|
|
||||||
* We want to actually check the paths rather than just the version string
|
|
||||||
* built into the executable, so that given version specification (and
|
|
||||||
* JAVA_VERSION_PATH) will yield the exact same Java environment, regardless
|
|
||||||
* of the version of the arbitrary launcher we start with.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ExecJRE(char *jre, char **argv)
|
|
||||||
{
|
|
||||||
char wanted[PATH_MAX];
|
|
||||||
const char* progname = GetProgramName();
|
|
||||||
const char* execname = NULL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Resolve the real path to the directory containing the selected JRE.
|
|
||||||
*/
|
|
||||||
if (realpath(jre, wanted) == NULL) {
|
|
||||||
JLI_ReportErrorMessage(JRE_ERROR9, jre);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Resolve the real path to the currently running launcher.
|
|
||||||
*/
|
|
||||||
SetExecname(argv);
|
|
||||||
execname = GetExecName();
|
|
||||||
if (execname == NULL) {
|
|
||||||
JLI_ReportErrorMessage(JRE_ERROR10);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the path to the selected JRE directory is a match to the initial
|
|
||||||
* portion of the path to the currently executing JRE, we have a winner!
|
|
||||||
* If so, just return.
|
|
||||||
*/
|
|
||||||
if (JLI_StrNCmp(wanted, execname, JLI_StrLen(wanted)) == 0)
|
|
||||||
return; /* I am the droid you were looking for */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This should never happen (because of the selection code in SelectJRE),
|
|
||||||
* but check for "impossibly" long path names just because buffer overruns
|
|
||||||
* can be so deadly.
|
|
||||||
*/
|
|
||||||
if (JLI_StrLen(wanted) + JLI_StrLen(progname) + 6 > PATH_MAX) {
|
|
||||||
JLI_ReportErrorMessage(JRE_ERROR11);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Construct the path and exec it.
|
|
||||||
*/
|
|
||||||
(void)JLI_StrCat(JLI_StrCat(wanted, "/bin/"), progname);
|
|
||||||
argv[0] = JLI_StringDup(progname);
|
|
||||||
if (JLI_IsTraceLauncher()) {
|
|
||||||
int i;
|
|
||||||
printf("ReExec Command: %s (%s)\n", wanted, argv[0]);
|
|
||||||
printf("ReExec Args:");
|
|
||||||
for (i = 1; argv[i] != NULL; i++)
|
|
||||||
printf(" %s", argv[i]);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
JLI_TraceLauncher("TRACER_MARKER:About to EXEC\n");
|
|
||||||
(void)fflush(stdout);
|
|
||||||
(void)fflush(stderr);
|
|
||||||
execv(wanted, argv);
|
|
||||||
JLI_ReportErrorMessageSys(JRE_ERROR12, wanted);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "Borrowed" from Solaris 10 where the unsetenv() function is being added
|
* "Borrowed" from Solaris 10 where the unsetenv() function is being added
|
||||||
* to libc thanks to SUSv3 (Standard Unix Specification, version 3). As
|
* to libc thanks to SUSv3 (Standard Unix Specification, version 3). As
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -36,7 +36,6 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include "manifest_info.h"
|
#include "manifest_info.h"
|
||||||
#include "version_comp.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define JVM_DLL "libjvm.so"
|
#define JVM_DLL "libjvm.so"
|
||||||
|
@ -100,10 +99,6 @@
|
||||||
* (incoming argv)
|
* (incoming argv)
|
||||||
* |
|
* |
|
||||||
* \|/
|
* \|/
|
||||||
* SelectVersion
|
|
||||||
* (selects the JRE version, note: not data model)
|
|
||||||
* |
|
|
||||||
* \|/
|
|
||||||
* CreateExecutionEnvironment
|
* CreateExecutionEnvironment
|
||||||
* (determines desired data model)
|
* (determines desired data model)
|
||||||
* |
|
* |
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -37,7 +37,6 @@
|
||||||
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include "java.h"
|
#include "java.h"
|
||||||
#include "version_comp.h"
|
|
||||||
|
|
||||||
#define JVM_DLL "jvm.dll"
|
#define JVM_DLL "jvm.dll"
|
||||||
#define JAVA_DLL "java.dll"
|
#define JAVA_DLL "java.dll"
|
||||||
|
@ -674,420 +673,6 @@ ServerClassMachine() {
|
||||||
return (GetErgoPolicy() == ALWAYS_SERVER_CLASS) ? JNI_TRUE : JNI_FALSE;
|
return (GetErgoPolicy() == ALWAYS_SERVER_CLASS) ? JNI_TRUE : JNI_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Determine if there is an acceptable JRE in the registry directory top_key.
|
|
||||||
* Upon locating the "best" one, return a fully qualified path to it.
|
|
||||||
* "Best" is defined as the most advanced JRE meeting the constraints
|
|
||||||
* contained in the manifest_info. If no JRE in this directory meets the
|
|
||||||
* constraints, return NULL.
|
|
||||||
*
|
|
||||||
* It doesn't matter if we get an error reading the registry, or we just
|
|
||||||
* don't find anything interesting in the directory. We just return NULL
|
|
||||||
* in either case.
|
|
||||||
*/
|
|
||||||
static char *
|
|
||||||
ProcessDir(manifest_info* info, HKEY top_key) {
|
|
||||||
DWORD index = 0;
|
|
||||||
HKEY ver_key;
|
|
||||||
char name[MAXNAMELEN];
|
|
||||||
int len;
|
|
||||||
char *best = NULL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enumerate "<top_key>/SOFTWARE/JavaSoft/Java Runtime Environment"
|
|
||||||
* searching for the best available version.
|
|
||||||
*/
|
|
||||||
while (RegEnumKey(top_key, index, name, MAXNAMELEN) == ERROR_SUCCESS) {
|
|
||||||
index++;
|
|
||||||
if (JLI_AcceptableRelease(name, info->jre_version))
|
|
||||||
if ((best == NULL) || (JLI_ExactVersionId(name, best) > 0)) {
|
|
||||||
if (best != NULL)
|
|
||||||
JLI_MemFree(best);
|
|
||||||
best = JLI_StringDup(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Extract "JavaHome" from the "best" registry directory and return
|
|
||||||
* that path. If no appropriate version was located, or there is an
|
|
||||||
* error in extracting the "JavaHome" string, return null.
|
|
||||||
*/
|
|
||||||
if (best == NULL)
|
|
||||||
return (NULL);
|
|
||||||
else {
|
|
||||||
if (RegOpenKeyEx(top_key, best, 0, KEY_READ, &ver_key)
|
|
||||||
!= ERROR_SUCCESS) {
|
|
||||||
JLI_MemFree(best);
|
|
||||||
if (ver_key != NULL)
|
|
||||||
RegCloseKey(ver_key);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
JLI_MemFree(best);
|
|
||||||
len = MAXNAMELEN;
|
|
||||||
if (RegQueryValueEx(ver_key, "JavaHome", NULL, NULL, (LPBYTE)name, &len)
|
|
||||||
!= ERROR_SUCCESS) {
|
|
||||||
if (ver_key != NULL)
|
|
||||||
RegCloseKey(ver_key);
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
if (ver_key != NULL)
|
|
||||||
RegCloseKey(ver_key);
|
|
||||||
return (JLI_StringDup(name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is the global entry point. It examines the host for the optimal
|
|
||||||
* JRE to be used by scanning a set of registry entries. This set of entries
|
|
||||||
* is hardwired on Windows as "Software\JavaSoft\Java Runtime Environment"
|
|
||||||
* under the set of roots "{ HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE }".
|
|
||||||
*
|
|
||||||
* This routine simply opens each of these registry directories before passing
|
|
||||||
* control onto ProcessDir().
|
|
||||||
*/
|
|
||||||
char *
|
|
||||||
LocateJRE(manifest_info* info) {
|
|
||||||
HKEY key = NULL;
|
|
||||||
char *path;
|
|
||||||
int key_index;
|
|
||||||
HKEY root_keys[2] = { HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE };
|
|
||||||
|
|
||||||
for (key_index = 0; key_index <= 1; key_index++) {
|
|
||||||
if (RegOpenKeyEx(root_keys[key_index], JRE_KEY, 0, KEY_READ, &key)
|
|
||||||
== ERROR_SUCCESS)
|
|
||||||
if ((path = ProcessDir(info, key)) != NULL) {
|
|
||||||
if (key != NULL)
|
|
||||||
RegCloseKey(key);
|
|
||||||
return (path);
|
|
||||||
}
|
|
||||||
if (key != NULL)
|
|
||||||
RegCloseKey(key);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Local helper routine to isolate a single token (option or argument)
|
|
||||||
* from the command line.
|
|
||||||
*
|
|
||||||
* This routine accepts a pointer to a character pointer. The first
|
|
||||||
* token (as defined by MSDN command-line argument syntax) is isolated
|
|
||||||
* from that string.
|
|
||||||
*
|
|
||||||
* Upon return, the input character pointer pointed to by the parameter s
|
|
||||||
* is updated to point to the remainding, unscanned, portion of the string,
|
|
||||||
* or to a null character if the entire string has been consummed.
|
|
||||||
*
|
|
||||||
* This function returns a pointer to a null-terminated string which
|
|
||||||
* contains the isolated first token, or to the null character if no
|
|
||||||
* token could be isolated.
|
|
||||||
*
|
|
||||||
* Note the side effect of modifying the input string s by the insertion
|
|
||||||
* of a null character, making it two strings.
|
|
||||||
*
|
|
||||||
* See "Parsing C Command-Line Arguments" in the MSDN Library for the
|
|
||||||
* parsing rule details. The rule summary from that specification is:
|
|
||||||
*
|
|
||||||
* * Arguments are delimited by white space, which is either a space or a tab.
|
|
||||||
*
|
|
||||||
* * A string surrounded by double quotation marks is interpreted as a single
|
|
||||||
* argument, regardless of white space contained within. A quoted string can
|
|
||||||
* be embedded in an argument. Note that the caret (^) is not recognized as
|
|
||||||
* an escape character or delimiter.
|
|
||||||
*
|
|
||||||
* * A double quotation mark preceded by a backslash, \", is interpreted as a
|
|
||||||
* literal double quotation mark (").
|
|
||||||
*
|
|
||||||
* * Backslashes are interpreted literally, unless they immediately precede a
|
|
||||||
* double quotation mark.
|
|
||||||
*
|
|
||||||
* * If an even number of backslashes is followed by a double quotation mark,
|
|
||||||
* then one backslash (\) is placed in the argv array for every pair of
|
|
||||||
* backslashes (\\), and the double quotation mark (") is interpreted as a
|
|
||||||
* string delimiter.
|
|
||||||
*
|
|
||||||
* * If an odd number of backslashes is followed by a double quotation mark,
|
|
||||||
* then one backslash (\) is placed in the argv array for every pair of
|
|
||||||
* backslashes (\\) and the double quotation mark is interpreted as an
|
|
||||||
* escape sequence by the remaining backslash, causing a literal double
|
|
||||||
* quotation mark (") to be placed in argv.
|
|
||||||
*/
|
|
||||||
static char*
|
|
||||||
nextarg(char** s) {
|
|
||||||
char *p = *s;
|
|
||||||
char *head;
|
|
||||||
int slashes = 0;
|
|
||||||
int inquote = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Strip leading whitespace, which MSDN defines as only space or tab.
|
|
||||||
* (Hence, no locale specific "isspace" here.)
|
|
||||||
*/
|
|
||||||
while (*p != (char)0 && (*p == ' ' || *p == '\t'))
|
|
||||||
p++;
|
|
||||||
head = p; /* Save the start of the token to return */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Isolate a token from the command line.
|
|
||||||
*/
|
|
||||||
while (*p != (char)0 && (inquote || !(*p == ' ' || *p == '\t'))) {
|
|
||||||
if (*p == '\\' && *(p+1) == '"' && slashes % 2 == 0)
|
|
||||||
p++;
|
|
||||||
else if (*p == '"')
|
|
||||||
inquote = !inquote;
|
|
||||||
slashes = (*p++ == '\\') ? slashes + 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the token isolated isn't already terminated in a "char zero",
|
|
||||||
* then replace the whitespace character with one and move to the
|
|
||||||
* next character.
|
|
||||||
*/
|
|
||||||
if (*p != (char)0)
|
|
||||||
*p++ = (char)0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Update the parameter to point to the head of the remaining string
|
|
||||||
* reflecting the command line and return a pointer to the leading
|
|
||||||
* token which was isolated from the command line.
|
|
||||||
*/
|
|
||||||
*s = p;
|
|
||||||
return (head);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Local helper routine to return a string equivalent to the input string
|
|
||||||
* s, but with quotes removed so the result is a string as would be found
|
|
||||||
* in argv[]. The returned string should be freed by a call to JLI_MemFree().
|
|
||||||
*
|
|
||||||
* The rules for quoting (and escaped quotes) are:
|
|
||||||
*
|
|
||||||
* 1 A double quotation mark preceded by a backslash, \", is interpreted as a
|
|
||||||
* literal double quotation mark (").
|
|
||||||
*
|
|
||||||
* 2 Backslashes are interpreted literally, unless they immediately precede a
|
|
||||||
* double quotation mark.
|
|
||||||
*
|
|
||||||
* 3 If an even number of backslashes is followed by a double quotation mark,
|
|
||||||
* then one backslash (\) is placed in the argv array for every pair of
|
|
||||||
* backslashes (\\), and the double quotation mark (") is interpreted as a
|
|
||||||
* string delimiter.
|
|
||||||
*
|
|
||||||
* 4 If an odd number of backslashes is followed by a double quotation mark,
|
|
||||||
* then one backslash (\) is placed in the argv array for every pair of
|
|
||||||
* backslashes (\\) and the double quotation mark is interpreted as an
|
|
||||||
* escape sequence by the remaining backslash, causing a literal double
|
|
||||||
* quotation mark (") to be placed in argv.
|
|
||||||
*/
|
|
||||||
static char*
|
|
||||||
unquote(const char *s) {
|
|
||||||
const char *p = s; /* Pointer to the tail of the original string */
|
|
||||||
char *un = (char*)JLI_MemAlloc(JLI_StrLen(s) + 1); /* Ptr to unquoted string */
|
|
||||||
char *pun = un; /* Pointer to the tail of the unquoted string */
|
|
||||||
|
|
||||||
while (*p != '\0') {
|
|
||||||
if (*p == '"') {
|
|
||||||
p++;
|
|
||||||
} else if (*p == '\\') {
|
|
||||||
const char *q = p + JLI_StrSpn(p,"\\");
|
|
||||||
if (*q == '"')
|
|
||||||
do {
|
|
||||||
*pun++ = '\\';
|
|
||||||
p += 2;
|
|
||||||
} while (*p == '\\' && p < q);
|
|
||||||
else
|
|
||||||
while (p < q)
|
|
||||||
*pun++ = *p++;
|
|
||||||
} else {
|
|
||||||
*pun++ = *p++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*pun = '\0';
|
|
||||||
return un;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Given a path to a jre to execute, this routine checks if this process
|
|
||||||
* is indeed that jre. If not, it exec's that jre.
|
|
||||||
*
|
|
||||||
* We want to actually check the paths rather than just the version string
|
|
||||||
* built into the executable, so that given version specification will yield
|
|
||||||
* the exact same Java environment, regardless of the version of the arbitrary
|
|
||||||
* launcher we start with.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ExecJRE(char *jre, char **argv) {
|
|
||||||
jint len;
|
|
||||||
char path[MAXPATHLEN + 1];
|
|
||||||
|
|
||||||
const char *progname = GetProgramName();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Resolve the real path to the currently running launcher.
|
|
||||||
*/
|
|
||||||
len = GetModuleFileName(NULL, path, MAXPATHLEN + 1);
|
|
||||||
if (len == 0 || len > MAXPATHLEN) {
|
|
||||||
JLI_ReportErrorMessageSys(JRE_ERROR9, progname);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
JLI_TraceLauncher("ExecJRE: old: %s\n", path);
|
|
||||||
JLI_TraceLauncher("ExecJRE: new: %s\n", jre);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the path to the selected JRE directory is a match to the initial
|
|
||||||
* portion of the path to the currently executing JRE, we have a winner!
|
|
||||||
* If so, just return.
|
|
||||||
*/
|
|
||||||
if (JLI_StrNCaseCmp(jre, path, JLI_StrLen(jre)) == 0)
|
|
||||||
return; /* I am the droid you were looking for */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If this isn't the selected version, exec the selected version.
|
|
||||||
*/
|
|
||||||
JLI_Snprintf(path, sizeof(path), "%s\\bin\\%s.exe", jre, progname);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Although Windows has an execv() entrypoint, it doesn't actually
|
|
||||||
* overlay a process: it can only create a new process and terminate
|
|
||||||
* the old process. Therefore, any processes waiting on the initial
|
|
||||||
* process wake up and they shouldn't. Hence, a chain of pseudo-zombie
|
|
||||||
* processes must be retained to maintain the proper wait semantics.
|
|
||||||
* Fortunately the image size of the launcher isn't too large at this
|
|
||||||
* time.
|
|
||||||
*
|
|
||||||
* If it weren't for this semantic flaw, the code below would be ...
|
|
||||||
*
|
|
||||||
* execv(path, argv);
|
|
||||||
* JLI_ReportErrorMessage("Error: Exec of %s failed\n", path);
|
|
||||||
* exit(1);
|
|
||||||
*
|
|
||||||
* The incorrect exec semantics could be addressed by:
|
|
||||||
*
|
|
||||||
* exit((int)spawnv(_P_WAIT, path, argv));
|
|
||||||
*
|
|
||||||
* Unfortunately, a bug in Windows spawn/exec impementation prevents
|
|
||||||
* this from completely working. All the Windows POSIX process creation
|
|
||||||
* interfaces are implemented as wrappers around the native Windows
|
|
||||||
* function CreateProcess(). CreateProcess() takes a single string
|
|
||||||
* to specify command line options and arguments, so the POSIX routine
|
|
||||||
* wrappers build a single string from the argv[] array and in the
|
|
||||||
* process, any quoting information is lost.
|
|
||||||
*
|
|
||||||
* The solution to this to get the original command line, to process it
|
|
||||||
* to remove the new multiple JRE options (if any) as was done for argv
|
|
||||||
* in the common SelectVersion() routine and finally to pass it directly
|
|
||||||
* to the native CreateProcess() Windows process control interface.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
char *cmdline;
|
|
||||||
char *p;
|
|
||||||
char *np;
|
|
||||||
char *ocl;
|
|
||||||
char *ccl;
|
|
||||||
char *unquoted;
|
|
||||||
DWORD exitCode;
|
|
||||||
STARTUPINFO si;
|
|
||||||
PROCESS_INFORMATION pi;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The following code block gets and processes the original command
|
|
||||||
* line, replacing the argv[0] equivalent in the command line with
|
|
||||||
* the path to the new executable and removing the appropriate
|
|
||||||
* Multiple JRE support options. Note that similar logic exists
|
|
||||||
* in the platform independent SelectVersion routine, but is
|
|
||||||
* replicated here due to the syntax of CreateProcess().
|
|
||||||
*
|
|
||||||
* The magic "+ 4" characters added to the command line length are
|
|
||||||
* 2 possible quotes around the path (argv[0]), a space after the
|
|
||||||
* path and a terminating null character.
|
|
||||||
*/
|
|
||||||
ocl = GetCommandLine();
|
|
||||||
np = ccl = JLI_StringDup(ocl);
|
|
||||||
p = nextarg(&np); /* Discard argv[0] */
|
|
||||||
cmdline = (char *)JLI_MemAlloc(JLI_StrLen(path) + JLI_StrLen(np) + 4);
|
|
||||||
if (JLI_StrChr(path, (int)' ') == NULL && JLI_StrChr(path, (int)'\t') == NULL)
|
|
||||||
cmdline = JLI_StrCpy(cmdline, path);
|
|
||||||
else
|
|
||||||
cmdline = JLI_StrCat(JLI_StrCat(JLI_StrCpy(cmdline, "\""), path), "\"");
|
|
||||||
|
|
||||||
while (*np != (char)0) { /* While more command-line */
|
|
||||||
p = nextarg(&np);
|
|
||||||
if (*p != (char)0) { /* If a token was isolated */
|
|
||||||
unquoted = unquote(p);
|
|
||||||
if (*unquoted == '-') { /* Looks like an option */
|
|
||||||
if (JLI_StrCmp(unquoted, "-classpath") == 0 ||
|
|
||||||
JLI_StrCmp(unquoted, "-cp") == 0) { /* Unique cp syntax */
|
|
||||||
cmdline = JLI_StrCat(JLI_StrCat(cmdline, " "), p);
|
|
||||||
p = nextarg(&np);
|
|
||||||
if (*p != (char)0) /* If a token was isolated */
|
|
||||||
cmdline = JLI_StrCat(JLI_StrCat(cmdline, " "), p);
|
|
||||||
} else if (JLI_StrNCmp(unquoted, "-version:", 9) != 0 &&
|
|
||||||
JLI_StrCmp(unquoted, "-jre-restrict-search") != 0 &&
|
|
||||||
JLI_StrCmp(unquoted, "-no-jre-restrict-search") != 0) {
|
|
||||||
cmdline = JLI_StrCat(JLI_StrCat(cmdline, " "), p);
|
|
||||||
}
|
|
||||||
} else { /* End of options */
|
|
||||||
cmdline = JLI_StrCat(JLI_StrCat(cmdline, " "), p);
|
|
||||||
cmdline = JLI_StrCat(JLI_StrCat(cmdline, " "), np);
|
|
||||||
JLI_MemFree((void *)unquoted);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
JLI_MemFree((void *)unquoted);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
JLI_MemFree((void *)ccl);
|
|
||||||
|
|
||||||
if (JLI_IsTraceLauncher()) {
|
|
||||||
np = ccl = JLI_StringDup(cmdline);
|
|
||||||
p = nextarg(&np);
|
|
||||||
printf("ReExec Command: %s (%s)\n", path, p);
|
|
||||||
printf("ReExec Args: %s\n", np);
|
|
||||||
JLI_MemFree((void *)ccl);
|
|
||||||
}
|
|
||||||
(void)fflush(stdout);
|
|
||||||
(void)fflush(stderr);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The following code is modeled after a model presented in the
|
|
||||||
* Microsoft Technical Article "Moving Unix Applications to
|
|
||||||
* Windows NT" (March 6, 1994) and "Creating Processes" on MSDN
|
|
||||||
* (Februrary 2005). It approximates UNIX spawn semantics with
|
|
||||||
* the parent waiting for termination of the child.
|
|
||||||
*/
|
|
||||||
memset(&si, 0, sizeof(si));
|
|
||||||
si.cb =sizeof(STARTUPINFO);
|
|
||||||
memset(&pi, 0, sizeof(pi));
|
|
||||||
|
|
||||||
if (!CreateProcess((LPCTSTR)path, /* executable name */
|
|
||||||
(LPTSTR)cmdline, /* command line */
|
|
||||||
(LPSECURITY_ATTRIBUTES)NULL, /* process security attr. */
|
|
||||||
(LPSECURITY_ATTRIBUTES)NULL, /* thread security attr. */
|
|
||||||
(BOOL)TRUE, /* inherits system handles */
|
|
||||||
(DWORD)0, /* creation flags */
|
|
||||||
(LPVOID)NULL, /* environment block */
|
|
||||||
(LPCTSTR)NULL, /* current directory */
|
|
||||||
(LPSTARTUPINFO)&si, /* (in) startup information */
|
|
||||||
(LPPROCESS_INFORMATION)&pi)) { /* (out) process information */
|
|
||||||
JLI_ReportErrorMessageSys(SYS_ERROR1, path);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_FAILED) {
|
|
||||||
if (GetExitCodeProcess(pi.hProcess, &exitCode) == FALSE)
|
|
||||||
exitCode = 1;
|
|
||||||
} else {
|
|
||||||
JLI_ReportErrorMessage(SYS_ERROR2);
|
|
||||||
exitCode = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseHandle(pi.hThread);
|
|
||||||
CloseHandle(pi.hProcess);
|
|
||||||
|
|
||||||
exit(exitCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wrapper for platform dependent unsetenv function.
|
* Wrapper for platform dependent unsetenv function.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -50,8 +50,7 @@ extern jlong Counter2Micros(jlong counts);
|
||||||
/*
|
/*
|
||||||
* Function prototypes.
|
* Function prototypes.
|
||||||
*/
|
*/
|
||||||
char *LocateJRE(manifest_info *info);
|
|
||||||
void ExecJRE(char *jre, char **argv);
|
|
||||||
int UnsetEnv(char *name);
|
int UnsetEnv(char *name);
|
||||||
|
|
||||||
#endif /* JAVA_MD_H */
|
#endif /* JAVA_MD_H */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -734,23 +734,6 @@ public class Arrrghs extends TestHelper {
|
||||||
System.out.println(tr);
|
System.out.println(tr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
static void testJreRestrictSearchFlag() {
|
|
||||||
// test both arguments to ensure they exist
|
|
||||||
TestResult tr = null;
|
|
||||||
tr = doExec(javaCmd,
|
|
||||||
"-no-jre-restrict-search", "-version");
|
|
||||||
tr.checkPositive();
|
|
||||||
if (!tr.testStatus)
|
|
||||||
System.out.println(tr);
|
|
||||||
|
|
||||||
tr = doExec(javaCmd,
|
|
||||||
"-jre-restrict-search", "-version");
|
|
||||||
tr.checkPositive();
|
|
||||||
if (!tr.testStatus)
|
|
||||||
System.out.println(tr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param args the command line arguments
|
* @param args the command line arguments
|
||||||
* @throws java.io.FileNotFoundException
|
* @throws java.io.FileNotFoundException
|
||||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue