--- old/test/java/lang/Runtime/exec/ConcurrentRead.java 2014-02-26 22:54:27.094262065 +0400 +++ new/test/java/lang/Runtime/exec/ConcurrentRead.java 2014-02-26 22:54:26.321885771 +0400 @@ -30,21 +30,17 @@ import java.io.InputStream; import java.io.OutputStream; -import java.io.File; -import java.io.IOException; public class ConcurrentRead { static volatile Exception savedException; - static final String TEE = "/usr/bin/tee"; public static void main(String[] args) throws Exception { - - if (File.separatorChar == '\\' || // Windows - !new File(TEE).exists()) // no tee + if (System.getProperty("os.name").startsWith("Windows")) { + System.err.println("Not for Windows"); return; - - Process p = Runtime.getRuntime().exec(TEE); + } + Process p = Runtime.getRuntime().exec(UnixCommands.tee()); OutputStream out = p.getOutputStream(); InputStream in = p.getInputStream(); Thread t1 = new WriterThread(out, in); --- old/test/java/lang/Runtime/exec/ExecWithDir.java 2014-02-26 22:54:28.606999057 +0400 +++ new/test/java/lang/Runtime/exec/ExecWithDir.java 2014-02-26 22:54:27.970689053 +0400 @@ -28,11 +28,11 @@ * directory is specified */ -import java.io.*; +import java.io.File; public class ExecWithDir { - private static final String CMD = "/bin/true"; + private static final String CMD = UnixCommands.true_(); private static final int N = 500; public static void main(String args[]) throws Exception { --- old/test/java/lang/Runtime/exec/ExecWithInput.java 2014-02-26 22:54:30.171761395 +0400 +++ new/test/java/lang/Runtime/exec/ExecWithInput.java 2014-02-26 22:54:29.547457241 +0400 @@ -39,7 +39,6 @@ public class ExecWithInput { - private static final String CAT = "/bin/cat"; private static final int N = 200; static int go(int i) throws Exception { @@ -50,8 +49,7 @@ * program exits. Under 1.4.1, cat sometimes gets stuck on a pipe * read and never terminates. */ - //Process p = Runtime.getRuntime().exec(new String[] { CAT } ); - Process p = Runtime.getRuntime().exec(CAT); + Process p = Runtime.getRuntime().exec(UnixCommands.cat()); String input = i + ": line 1\n" + i + ": line 2\n"; StringBufferInputStream in = new StringBufferInputStream(input); @@ -65,10 +63,8 @@ } public static void main(String[] args) throws Exception { - if (!System.getProperty("os.name").equals("Linux")) - return; - if (File.separatorChar == '\\') { - // no /bin/cat on windows + if (! System.getProperty("os.name").startsWith("Linux")) { + System.err.println("Only for Linux"); return; } for (int i = 0; i < N; i++) @@ -93,7 +89,6 @@ public void run() { try { - int c; byte[] buf = new byte[8192]; int n; while ((n = in.read(buf)) != -1) { --- old/test/java/lang/Runtime/exec/ExitValue.java 2014-02-26 22:54:31.768539331 +0400 +++ new/test/java/lang/Runtime/exec/ExitValue.java 2014-02-26 22:54:31.108217627 +0400 @@ -68,7 +68,7 @@ int expectedExitValue) throws Exception { - checkExitValue(new String[] { "/bin/sh", "-c", posixShellProgram }, + checkExitValue(new String[] { UnixCommands.sh(), "-c", posixShellProgram }, expectedExitValue); } @@ -85,16 +85,16 @@ "ExitValue$Run", String.valueOf(EXIT_CODE) }, EXIT_CODE); - checkExitValue(new String[] { "/bin/true" }, 0); + checkExitValue(new String[] { UnixCommands.true_() }, 0); checkPosixShellExitValue("exit", 0); checkPosixShellExitValue("exit 7", 7); - if (new File("/bin/kill").exists()) { + if (new File(UnixCommands.kill()).exists()) { int sigoffset = System.getProperty("os.name").equals("SunOS") ? 0 : 128; - checkPosixShellExitValue("/bin/kill -9 $$", sigoffset+9); + checkPosixShellExitValue(UnixCommands.kill() + " -9 $$", sigoffset+9); } } --- old/test/java/lang/Runtime/exec/LotsOfDestroys.java 2014-02-26 22:54:33.333301669 +0400 +++ new/test/java/lang/Runtime/exec/LotsOfDestroys.java 2014-02-26 22:54:32.624956569 +0400 @@ -26,21 +26,19 @@ * @bug 4637504 4653814 * @summary Destroy should close stderr, stdout and stdin * @author kladko + * @run main/othervm LotsOfDestroys */ -import java.io.File; - public class LotsOfDestroys { static final int RUNS = 400; - static final String ECHO = "/usr/bin/echo"; public static void main(String[] args) throws Exception { - if (File.separatorChar == '\\' || // Windows - !new File(ECHO).exists()) // no echo + if (System.getProperty("os.name").startsWith("Windows")) { + System.err.println("Not for Windows"); return; - + } for (int i = 0; i<= RUNS; i++) { - Process process = Runtime.getRuntime().exec(ECHO + " x"); + Process process = Runtime.getRuntime().exec(UnixCommands.echo() + " x"); process.destroy(); } } --- old/test/java/lang/Runtime/exec/LotsOfOutput.java 2014-02-26 22:54:34.878054259 +0400 +++ new/test/java/lang/Runtime/exec/LotsOfOutput.java 2014-02-26 22:54:34.253750103 +0400 @@ -26,18 +26,17 @@ * @bug 4369826 * @summary Process with lots of output should not crash VM * @author kladko + * @run main/othervm LotsOfOutput */ -import java.io.File; - public class LotsOfOutput { - static final String CAT = "/usr/bin/cat"; - public static void main(String[] args) throws Exception{ - if (File.separatorChar == '\\' || // Windows - !new File(CAT).exists()) // no cat + public static void main(String[] args) throws Exception { + if (System.getProperty("os.name").startsWith("Windows")) { + System.err.println("Not for Windows"); return; - Process p = Runtime.getRuntime().exec(CAT + " /dev/zero"); + } + Process p = Runtime.getRuntime().exec(UnixCommands.cat() + " /dev/zero"); long initMemory = Runtime.getRuntime().totalMemory(); for (int i=1; i< 10; i++) { Thread.sleep(100); --- old/test/java/lang/Runtime/exec/SleepyCat.java 2014-02-26 22:54:36.462826345 +0400 +++ new/test/java/lang/Runtime/exec/SleepyCat.java 2014-02-26 22:54:35.822514392 +0400 @@ -73,8 +73,8 @@ // slower, making the child more likely to win the race! int iterations = 20; int timeout = 30; - String[] catArgs = new String[] {"/bin/cat"}; - String[] sleepArgs = new String[] {"/bin/sleep", + String[] catArgs = new String[] {UnixCommands.cat()}; + String[] sleepArgs = new String[] {UnixCommands.sleep(), String.valueOf(timeout+1)}; Process[] cats = new Process[iterations]; Process[] sleeps = new Process[iterations]; @@ -126,8 +126,9 @@ timer.schedule(sleeperExecutioner, timeout * 1000); byte[] buffer = new byte[10]; String[] args = - new String[] {"/bin/sh", "-c", - "exec sleep " + (timeout+1) + " >/dev/null"}; + new String[] {UnixCommands.sh(), "-c", + "exec " + UnixCommands.sleep() + " " + + (timeout+1) + " >/dev/null"}; for (int i = 0; i < backgroundSleepers.length && !sleeperExecutioner.timedOut(); --- old/test/java/lang/Runtime/exec/Status.java 2014-02-26 22:54:38.299721265 +0400 +++ new/test/java/lang/Runtime/exec/Status.java 2014-02-26 22:54:37.643401512 +0400 @@ -35,10 +35,12 @@ public static void main(String args[]) throws Exception { - if (!System.getProperty("os.name").equals("Linux")) + if (!System.getProperty("os.name").equals("Linux")) { + System.err.println("Only for Linux"); return; + } for (int i = 0; i < N; i++) { - Process p = Runtime.getRuntime().exec("false"); + Process p = Runtime.getRuntime().exec(UnixCommands.false_()); int s = p.waitFor(); System.out.print(s); System.out.print(' '); --- old/test/java/lang/Runtime/exec/StreamsSurviveDestroy.java 2014-02-26 22:54:40.096596686 +0400 +++ new/test/java/lang/Runtime/exec/StreamsSurviveDestroy.java 2014-02-26 22:54:39.296206742 +0400 @@ -30,7 +30,6 @@ import java.io.*; import java.util.concurrent.*; - public class StreamsSurviveDestroy { private static class Copier extends Thread { @@ -102,7 +101,7 @@ CountDownLatch latch = new CountDownLatch(2); System.err.println("test"); - Process p = Runtime.getRuntime().exec("/bin/cat"); + Process p = Runtime.getRuntime().exec(UnixCommands.cat()); Copier cp1 = new Copier("out", p.getInputStream(), System.err, false, false, latch); Copier cp2 = new Copier("err", p.getErrorStream(), System.err, @@ -122,7 +121,7 @@ CountDownLatch latch = new CountDownLatch(2); System.err.println("testCloseBeforeDestroy"); - Process p = Runtime.getRuntime().exec("/bin/cat"); + Process p = Runtime.getRuntime().exec(UnixCommands.cat()); Copier cp1 = new Copier("out", p.getInputStream(), System.err, true, false, latch); Copier cp2 = new Copier("err", p.getErrorStream(), System.err, @@ -143,7 +142,7 @@ static void testCloseAfterDestroy() throws Exception { CountDownLatch latch = new CountDownLatch(2); System.err.println("testCloseAfterDestroy"); - Process p = Runtime.getRuntime().exec("/bin/cat"); + Process p = Runtime.getRuntime().exec(UnixCommands.cat()); Copier cp1 = new Copier("out", p.getInputStream(), System.err, true, false,latch); Copier cp2 = new Copier("err", p.getErrorStream(), System.err, @@ -165,7 +164,7 @@ static void testInterrupt() throws Exception { CountDownLatch latch = new CountDownLatch(2); System.err.println("testInterrupt"); - Process p = Runtime.getRuntime().exec("/bin/cat"); + Process p = Runtime.getRuntime().exec(UnixCommands.cat()); Copier cp1 = new Copier("out", p.getInputStream(), System.err, false, true, latch); Copier cp2 = new Copier("err", p.getErrorStream(), System.err, @@ -188,8 +187,10 @@ // Applies only to Solaris; Linux and Windows // behave a little differently - if (!System.getProperty("os.name").equals("SunOS")) + if (!System.getProperty("os.name").equals("SunOS")) { + System.err.println("For SunOS only"); return; + } test(); testCloseBeforeDestroy(); --- /dev/null 2014-02-26 09:32:43.186606359 +0400 +++ new/test/java/lang/Runtime/exec/UnixCommands.java 2014-02-26 22:54:40.904990527 +0400 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2014, 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. + * + * 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. + */ + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +/** + * Utility class for finding the command on the current system + */ +public class UnixCommands { + + private static final String[] paths = {"/bin", "/usr/bin", + "/usr/local/bin", "/system/bin", "/sbin", "/usr/bin/sbin", + "/usr/local/sbin", "/system/sbin"}; + + private static Map nameToCommand = new HashMap<>(16); + + /** + * If can find the path to the command, returns the command with the full path. + * Otherwise, returns the name of the command. + */ + public static String cat() { return findCommand("cat"); } + public static String sh() { return findCommand("sh"); } + public static String kill() { return findCommand("kill"); } + public static String sleep() { return findCommand("sleep"); } + public static String tee() { return findCommand("tee"); } + public static String echo() { return findCommand("echo"); } + public static String true_() { return findCommand("true"); } + public static String false_() { return findCommand("false"); } + + public static String findCommand(String name) { + if (nameToCommand.containsKey(name)) { + return nameToCommand.get(name); + } + String command = findCommand0(name); + nameToCommand.put(name, command); + return command; + } + + private static String findCommand0(String name) { + for (String path : paths) { + String command = path + '/' + name; + if (new File(command).canExecute()) { + return command; + } + } + return name; + } +}