15f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes/*
25f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * Licensed to the Apache Software Foundation (ASF) under one or more
35f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * contributor license agreements.  See the NOTICE file distributed with
45f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * this work for additional information regarding copyright ownership.
55f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * The ASF licenses this file to You under the Apache License, Version 2.0
65f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * (the "License"); you may not use this file except in compliance with
75f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * the License.  You may obtain a copy of the License at
85f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes *
95f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes *     http://www.apache.org/licenses/LICENSE-2.0
105f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes *
115f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes *  Unless required by applicable law or agreed to in writing, software
125f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes *  distributed under the License is distributed on an "AS IS" BASIS,
135f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes *
155f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes *  See the License for the specific language governing permissions and
165f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes *  limitations under the License.
175f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */
185f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
195f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes/**
205f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * @author Vitaly A. Provodin
215f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */
225f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
235f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughespackage org.apache.harmony.jpda.tests.jdwp.share;
245f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
255f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughesimport java.io.IOException;
265f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughesimport java.util.Vector;
275f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
285f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughesimport org.apache.harmony.jpda.tests.framework.LogWriter;
295f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughesimport org.apache.harmony.jpda.tests.framework.StreamRedirector;
305f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughesimport org.apache.harmony.jpda.tests.framework.TestErrorException;
315f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughesimport org.apache.harmony.jpda.tests.framework.jdwp.JDWPDebuggeeWrapper;
325f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughesimport org.apache.harmony.jpda.tests.share.JPDATestOptions;
335f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
345f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes/**
355f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * This class provides basic DebuggeeWrapper implementation based on JUnit framework,
365f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes * which can launch and control debuggee process.
375f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes */
385f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughespublic class JDWPUnitDebuggeeProcessWrapper extends JDWPDebuggeeWrapper {
395f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
405f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    /**
415f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     * Target VM debuggee process.
425f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     */
435f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    public Process process;
445f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
455f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    protected StreamRedirector errRedir;
465f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    protected StreamRedirector outRedir;
475f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
485f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    /**
495f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     * Creates new instance with given data.
505f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     *
515f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     * @param settings
525f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     *            test run options
535f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     * @param logWriter
545f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     *            where to print log messages
555f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     */
565f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    public JDWPUnitDebuggeeProcessWrapper(JPDATestOptions settings, LogWriter logWriter) {
575f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        super(settings, logWriter);
585f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    }
595f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
605f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    /**
615f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     * Launches process and redirects output.
625f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     */
635f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    public void launchProcessAndRedirectors(String cmdLine) throws IOException {
645f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        logWriter.println("Launch process: " + cmdLine);
655f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        process = launchProcess(cmdLine);
665f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        logWriter.println("Launched process");
675f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        if (process != null) {
685f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            logWriter.println("Start redirectors");
695f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            errRedir = new StreamRedirector(process.getErrorStream(), logWriter, "STDERR");
705f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            errRedir.setDaemon(true);
715f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            errRedir.start();
725f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            outRedir = new StreamRedirector(process.getInputStream(), logWriter, "STDOUT");
735f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            outRedir.setDaemon(true);
745f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            outRedir.start();
755f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            logWriter.println("Started redirectors");
765f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        }
775f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    }
785f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
795f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    /**
805f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     * Waits for process to exit and closes uotput redirectors
815f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     */
825f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    public void finishProcessAndRedirectors() {
835f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        if (process != null) {
845f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            try {
855f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                logWriter.println("Waiting for process exit");
865f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                WaitForProcessExit(process);
875f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                logWriter.println("Finished process");
885f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            } catch (IOException e) {
895f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                throw new TestErrorException("IOException in waiting for process exit: ", e);
905f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            }
915f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
925f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            logWriter.println("Waiting for redirectors finish");
935f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            if (outRedir != null) {
945f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                outRedir.exit();
955f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                try {
965f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    outRedir.join(settings.getTimeout());
975f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                } catch (InterruptedException e) {
985f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    logWriter.println("InterruptedException in stopping outRedirector: " + e);
995f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                }
1005f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                if (outRedir.isAlive()) {
1015f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    logWriter.println("WARNING: redirector not stopped: " + outRedir.getName());
1025f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                }
1035f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            }
1045f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            if (errRedir != null) {
1055f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                errRedir.exit();
1065f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                try {
1075f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    errRedir.join(settings.getTimeout());
1085f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                } catch (InterruptedException e) {
1095f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    logWriter.println("InterruptedException in stopping errRedirector: " + e);
1105f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                }
1115f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                if (errRedir.isAlive()) {
1125f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    logWriter.println("WARNING: redirector not stopped: " + errRedir.getName());
1135f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                }
1145f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            }
1155f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            logWriter.println("Finished redirectors");
1165f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        }
1175f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    }
1185f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
1195f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    /**
1205f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     * Launches process with given command line.
1215f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     *
1225f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     * @param cmdLine
1235f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     *            command line
1245f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     * @return associated Process object or null if not available
1255f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     * @throws IOException
1265f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     *             if error occurred in launching process
1275f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     */
1285f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    protected Process launchProcess(String cmdLine) throws IOException {
1295f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
1305f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    	// Runtime.exec(String) does not preserve quoted arguments
1315f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    	// process = Runtime.getRuntime().exec(cmdLine);
1325f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
1335f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    	String args[] = splitCommandLine(cmdLine);
1345f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    	process = Runtime.getRuntime().exec(args);
1355f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        return process;
1365f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    }
1375f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
1385f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    /**
1395f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     * Splits command line into arguments preserving spaces in quoted arguments
1405f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     * either with single and double quotes (not prefixed by '\').
1415f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     *
1425f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     * @param cmdLine
1435f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     *            command line
1445f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     * @return associated Process object or null if not available
1455f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     * @throws IOException
1465f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     *             if error occurred in launching process
1475f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     */
1485f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes/*
1495f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    public String[] splitCommandLine(String cmd) {
1505f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
1515f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        // allocate array for parsed arguments
1525f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        int max_argc = 250;
1535f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        Vector argv = new Vector();
1545f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
1555f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        // parse command line
1565f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        int len = cmd.length();
1575f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        if (len > 0) {
1585f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            for (int arg = 0; arg < len;) {
1595f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                // skip initial spaces
1605f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                while (Character.isWhitespace(cmd.charAt(arg))) arg++;
1615f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                // parse non-spaced or quoted argument
1625f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                for (int p = arg; ; p++) {
1635f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    // check for ending separator
1645f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    if (p >= len || Character.isWhitespace(cmd.charAt(p))) {
1655f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    	if (p > len) p = len;
1665f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    	String val = cmd.substring(arg, p);
1675f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                        argv.add(val);
1685f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                        arg = p + 1;
1695f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                        break;
1705f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    }
1715f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
1725f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    // check for starting quote
1735f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    if (cmd.charAt(p) == '\"') {
1745f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                         char quote = cmd.charAt(p++);
1755f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                         // skip all chars until terminating quote or end of line
1765f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                         for (; p < len; p++) {
1775f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                             // check for terminating quote
1785f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                             if (cmd.charAt(p) == quote)
1795f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                            	 break;
1805f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                             // skip escaped quote
1815f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                             if (cmd.charAt(p) == '\\' && (p+1) < len && cmd.charAt(p+1) == quote)
1825f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                            	 p++;
1835f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                         }
1845f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                     }
1855f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
1865f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    // skip escaped quote
1875f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    if (cmd.charAt(p) == '\\' && (p+1) < len && cmd.charAt(p+1) == '\"') {
1885f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    	p++;
1895f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    }
1905f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                }
1915f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            }
1925f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        }
1935f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
1945f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    	logWriter.println("Splitted command line: " + argv);
1955f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        int size = argv.size();
1965f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        String args[] = new String[size];
1975f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        return (String[])argv.toArray(args);
1985f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes	}
1995f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes*/
2005f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    public String[] splitCommandLine(String cmd) {
2015f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
2025f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        int len = cmd.length();
2035f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        char chars[] = new char[len];
2045f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        Vector<String> argv = new Vector<String>();
2055f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
2065f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        if (len > 0) {
2075f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            for (int arg = 0; arg < len;) {
2085f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                // skip initial spaces
2095f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                while (Character.isWhitespace(cmd.charAt(arg))) arg++;
2105f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                // parse non-spaced or quoted argument
2115f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                for (int p = arg, i = 0; ; p++) {
2125f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    // check for starting quote
2135f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    if (p < len && (cmd.charAt(p) == '\"' || cmd.charAt(p) == '\'')) {
2145f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                         char quote = cmd.charAt(p++);
2155f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                         // copy all chars until terminating quote or end of line
2165f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                         for (; p < len; p++) {
2175f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                             // check for terminating quote
2185f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                             if (cmd.charAt(p) == quote) {
2195f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                            	 p++;
2205f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                            	 break;
2215f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                             }
2225f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                             // preserve escaped quote
2235f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                             if (cmd.charAt(p) == '\\' && (p+1) < len && cmd.charAt(p+1) == quote)
2245f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                            	 p++;
2255f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                             chars[i++] = cmd.charAt(p);
2265f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                         }
2275f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                     }
2285f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
2295f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    // check for ending separator
2305f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    if (p >= len || Character.isWhitespace(cmd.charAt(p))) {
2315f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    	String val = new String(chars, 0, i);
2325f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                        argv.add(val);
2335f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                        arg = p + 1;
2345f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                        break;
2355f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    }
2365f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
2375f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    // preserve escaped quote
2385f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    if (cmd.charAt(p) == '\\' && (p+1) < len
2395f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    		&& (cmd.charAt(p+1) == '\"' || cmd.charAt(p+1) == '\'')) {
2405f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    	p++;
2415f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    }
2425f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
2435f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    // copy current char
2445f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                    chars[i++] = cmd.charAt(p);
2455f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                }
2465f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            }
2475f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        }
2485f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
2495f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    	logWriter.println("Splitted command line: " + argv);
2505f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        int size = argv.size();
2515f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        String args[] = new String[size];
2525f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        return (String[])argv.toArray((String[])args);
2535f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes	}
2545f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
2555f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    /**
2565f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     * Waits for launched process to exit.
2575f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     *
2585f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     * @param process
2595f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     *            associated Process object or null if not available
2605f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     * @throws IOException
2615f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     *             if any exception occurs in waiting
2625f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     */
2635f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    protected void WaitForProcessExit(Process process) throws IOException {
2645f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        ProcessWaiter thrd = new ProcessWaiter();
2655f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        thrd.setDaemon(true);
2665f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        thrd.start();
2675f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        try {
2685f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            thrd.join(settings.getTimeout());
2695f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        } catch (InterruptedException e) {
2705f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            throw new TestErrorException(e);
2715f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        }
2725f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
2735f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        if (thrd.isAlive()) {
2745f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            thrd.interrupt();
2755f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        }
2765f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
2775f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        try {
2785f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            int exitCode = process.exitValue();
2795f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            logWriter.println("Finished debuggee with exit code: " + exitCode);
2805f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        } catch (IllegalThreadStateException e) {
2815f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            logWriter.printError("Terminate debuggee process");
2825f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            process.destroy();
2835f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            throw new TestErrorException("Debuggee process did not finish during timeout", e);
2845f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        }
2855f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
2865f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        // dispose any resources of the process
2875f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        process.destroy();
2885f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    }
2895f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
2905f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    /**
2915f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     * Separate thread for waiting for process exit for specified timeout.
2925f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes     */
2935f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    class ProcessWaiter extends Thread {
2945f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        public void run() {
2955f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            try {
2965f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                process.waitFor();
2975f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            } catch (InterruptedException e) {
2985f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes                logWriter.println("Ignoring exception in ProcessWaiter thread interrupted: " + e);
2995f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes            }
3005f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes        }
3015f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    }
3025f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
3035f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    public void start() {
3045f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    }
3055f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes
3065f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    public void stop() {
3075f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes    }
3085f0a23683aa603d8c50b6dd071a565821b76067bElliott Hughes}
309