--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/Arrrghs.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,206 @@
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. 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.
+ *
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+
+public class Arrrghs{
+
+ /**
+ * A group of tests to ensure that arguments are passed correctly to
+ * a child java process upon a re-exec, this typically happens when
+ * a version other than the one being executed is requested by the user.
+ *
+ * History: these set of tests were part of Arrrghs.sh. The MKS shell
+ * implementations are notoriously buggy. Implementing these tests purely
+ * in Java is not only portable but also robust.
+ *
+ */
+
+ /* Do not instantiate */
+ private Arrrghs() {}
+
+ static String javaCmd;
+
+ // The version string to force a re-exec
+ final static String VersionStr = "-version:1.1+";
+
+ // The Cookie or the pattern we match in the debug output.
+ final static String Cookie = "ReExec Args: ";
+
+ private static boolean _debug = Boolean.getBoolean("Arrrghs.Debug");
+ private static boolean isWindows = System.getProperty("os.name", "unknown").startsWith("Windows");
+ private static int exitValue = 0;
+
+ private static void doUsage(String message) {
+ if (message != null) System.out.println("Error: " + message);
+ System.out.println("Usage: Arrrghs path_to_java");
+ System.exit(1);
+ }
+
+ /*
+ * SIGH, On Windows all strings are quoted, we need to unwrap it
+ */
+ private static String removeExtraQuotes(String in) {
+ if (isWindows) {
+ // Trim the string and remove the enclosed quotes if any.
+ in = in.trim();
+ if (in.startsWith("\"") && in.endsWith("\"")) {
+ return in.substring(1, in.length()-1);
+ }
+ }
+ return in;
+ }
+
+
+ /*
+ * This method detects the cookie in the output stream of the process.
+ */
+ private static boolean detectCookie(InputStream istream, String expectedArguments) throws IOException {
+ BufferedReader rd = new BufferedReader(new InputStreamReader(istream));
+ boolean retval = false;
+
+ String in = rd.readLine();
+ while (in != null) {
+ if (_debug) System.out.println(in);
+ if (in.startsWith(Cookie)) {
+ String detectedArgument = removeExtraQuotes(in.substring(Cookie.length()));
+ if (expectedArguments.equals(detectedArgument)) {
+ retval = true;
+ } else {
+ System.out.println("Error: Expected Arguments\t:'" + expectedArguments + "'");
+ System.out.println(" Detected Arguments\t:'" + detectedArgument + "'");
+ }
+ // Return the value asap if not in debug mode.
+ if (!_debug) {
+ rd.close();
+ istream.close();
+ return retval;
+ }
+ }
+ in = rd.readLine();
+ }
+ return retval;
+ }
+
+
+
+ private static boolean doExec0(ProcessBuilder pb, String expectedArguments) {
+ boolean retval = false;
+ try {
+ pb.redirectErrorStream(_debug);
+ Process p = pb.start();
+ retval = detectCookie(p.getInputStream(), expectedArguments);
+ p.waitFor();
+ p.destroy();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ throw new RuntimeException(ex.getMessage());
+ }
+ return retval;
+ }
+
+ /**
+ * This method return true if the expected and detected arguments are the same.
+ * Quoting could cause dissimilar testArguments and expected arguments.
+ */
+ static boolean doExec(String testArguments, String expectedPattern) {
+ ProcessBuilder pb = new ProcessBuilder(javaCmd, VersionStr, testArguments);
+
+ Map<String, String> env = pb.environment();
+ env.put("_JAVA_LAUNCHER_DEBUG", "true");
+ return doExec0(pb, testArguments);
+ }
+
+ /**
+ * A convenience method for identical test pattern and expected arguments
+ */
+ static boolean doExec(String testPattern) {
+ return doExec(testPattern, testPattern);
+ }
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String[] args) {
+ if (args.length < 1 && args[0] == null) {
+ doUsage("Invalid number of arguments");
+ }
+
+ javaCmd = args[0];
+
+ if (!new File(javaCmd).canExecute()) {
+ if (isWindows && new File(javaCmd + ".exe").canExecute()) {
+ javaCmd = javaCmd + ".exe";
+ } else {
+ doUsage("The java executable must exist");
+ }
+ }
+
+
+ if (_debug) System.out.println("Starting Arrrghs tests");
+ // Basic test
+ if (!doExec("-a -b -c -d")) exitValue++;
+
+ // Basic test with many spaces
+ if (!doExec("-a -b -c -d")) exitValue++;
+
+ // Quoted whitespace does matter ?
+ if (!doExec("-a \"\"-b -c\"\" -d")) exitValue++;
+
+ // Escaped quotes outside of quotes as literals
+ if (!doExec("-a \\\"-b -c\\\" -d")) exitValue++;
+
+ // Check for escaped quotes inside of quotes as literal
+ if (!doExec("-a \"-b \\\"stuff\\\"\" -c -d")) exitValue++;
+
+ // A quote preceeded by an odd number of slashes is a literal quote
+ if (!doExec("-a -b\\\\\\\" -c -d")) exitValue++;
+
+ // A quote preceeded by an even number of slashes is a literal quote
+ // see 6214916.
+ if (!doExec("-a -b\\\\\\\\\" -c -d")) exitValue++;
+
+ // Make sure that whitespace doesn't interfere with the removal of the
+ // appropriate tokens. (space-tab-space preceeds -jre-restict-search).
+ if (!doExec("-a -b \t -jre-restrict-search -c -d","-a -b -c -d")) exitValue++;
+
+ // Make sure that the mJRE tokens being stripped, aren't stripped if
+ // they happen to appear as arguments to the main class.
+ if (!doExec("foo -version:1.1+")) exitValue++;
+
+ System.out.println("Completed Arrrghs arguments quoting/matching tests with " + exitValue + " errors");
+ System.exit(exitValue);
+ }
+
+}