/*
 * Copyright (c) 2003, 2025, 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.
 */

/*
 * @test
 * @bug 4199068 4738465 4937983 4930681 4926230 4931433 4932663 4986689
 *      5026830 5023243 5070673 4052517 4811767 6192449 6397034 6413313
 *      6464154 6523983 6206031 4960438 6631352 6631966 6850957 6850958
 *      4947220 7018606 7034570 4244896 5049299 8003488 8054494 8058464
 *      8067796 8224905 8263729 8265173 8272600 8231297 8282219 8285517
 *      8352533 8368192
 * @key intermittent
 * @summary Basic tests for Process and Environment Variable code
 * @modules java.base/java.lang:open
 *          java.base/java.io:open
 * @requires !vm.musl
 * @requires vm.flagless
 * @library /test/lib
 * @run main/othervm/native/timeout=360 Basic
 * @run main/othervm/native/timeout=360 -Djdk.lang.Process.launchMechanism=fork Basic
 * @author Martin Buchholz
 */

/*
 * @test
 * @modules java.base/java.lang:open
 *          java.base/java.io:open
 *          java.base/jdk.internal.misc
 * @requires (os.family == "linux" & !vm.musl)
 * @library /test/lib
 * @run main/othervm/timeout=300 -Djdk.lang.Process.launchMechanism=posix_spawn Basic
 */

import java.lang.ProcessBuilder.Redirect;
import java.lang.ProcessHandle;
import static java.lang.ProcessBuilder.Redirect.*;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import static java.lang.System.getenv;
import static java.lang.System.out;
import static java.lang.Boolean.TRUE;
import static java.util.AbstractMap.SimpleImmutableEntry;

import jdk.test.lib.Platform;

public class Basic {

    /* used for Windows only */
    static final String systemRoot = System.getenv("SystemRoot");

    /* used for Mac OS X only */
    static final String cfUserTextEncoding = System.getenv("__CF_USER_TEXT_ENCODING");

    /* used for AIX only */
    static final String libpath = System.getenv("LIBPATH");

    /* Used for regex String matching for long error messages */
    static final String PERMISSION_DENIED_ERROR_MSG = "(Permission denied|error=13)";
    static final String NO_SUCH_FILE_ERROR_MSG = "(No such file|error=2)";
    static final String SPAWNHELPER_FAILURE_MSG = "(Possible reasons:)";

    /**
     * Returns the number of milliseconds since time given by
     * startNanoTime, which must have been previously returned from a
     * call to {@link System#nanoTime()}.
     */
    private static long millisElapsedSince(long startNanoTime) {
        return TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanoTime);
    }

    private static String commandOutput(Reader r) throws Throwable {
        StringBuilder sb = new StringBuilder();
        int c;
        while ((c = r.read()) > 0)
            if (c != '\r')
                sb.append((char) c);
        return sb.toString();
    }

    private static String commandOutput(Process p) throws Throwable {
        check(p.getInputStream()  == p.getInputStream());
        check(p.getOutputStream() == p.getOutputStream());
        check(p.getErrorStream()  == p.getErrorStream());
        Reader r = new InputStreamReader(p.getInputStream(),"UTF-8");
        String output = commandOutput(r);
        equal(p.waitFor(), 0);
        equal(p.exitValue(), 0);
        // The debug/fastdebug versions of the VM may write some warnings to stdout
        // (i.e. "Warning:  Cannot open log file: hotspot.log" if the VM is started
        // in a directory without write permissions). These warnings will confuse tests
        // which match the entire output of the child process so better filter them out.
        return output.replaceAll("Warning:.*\\n", "");
    }

    private static String commandOutput(ProcessBuilder pb) {
        try {
            return commandOutput(pb.start());
        } catch (Throwable t) {
            String commandline = "";
            for (String arg : pb.command())
                commandline += " " + arg;
            System.out.println("Exception trying to run process: " + commandline);
            unexpected(t);
            return "";
        }
    }

    private static String commandOutput(String...command) {
        try {
            return commandOutput(Runtime.getRuntime().exec(command));
        } catch (Throwable t) {
            String commandline = "";
            for (String arg : command)
                commandline += " " + arg;
            System.out.println("Exception trying to run process: " + commandline);
            unexpected(t);
            return "";
        }
    }

    private static void checkCommandOutput(ProcessBuilder pb,
                                           String expected,
                                           String failureMsg) {
        String got = commandOutput(pb);
        check(got.equals(expected),
              failureMsg + "\n" +
              "Expected: \"" + expected + "\"\n" +
              "Got: \"" + got + "\"");
    }

    private static String absolutifyPath(String path) {
        StringBuilder sb = new StringBuilder();
        for (String file : path.split(File.pathSeparator)) {
            if (sb.length() != 0)
                sb.append(File.pathSeparator);
            sb.append(new File(file).getAbsolutePath());
        }
        return sb.toString();
    }

    // compare windows-style, by canonicalizing to upper case,
    // not lower case as String.compareToIgnoreCase does
    private static class WindowsComparator
        implements Comparator<String> {
        public int compare(String x, String y) {
            return x.toUpperCase(Locale.US)
                .compareTo(y.toUpperCase(Locale.US));
        }
    }

    private static String sortedLines(String lines) {
        String[] arr = lines.split("\n");
        List<String> ls = new ArrayList<String>();
        for (String s : arr)
            ls.add(s);
        Collections.sort(ls, new WindowsComparator());
        StringBuilder sb = new StringBuilder();
        for (String s : ls)
            sb.append(s + "\n");
        return sb.toString();
    }

    private static void compareLinesIgnoreCase(String lines1, String lines2) {
        if (! (sortedLines(lines1).equalsIgnoreCase(sortedLines(lines2)))) {
            String dashes =
                "-----------------------------------------------------";
            out.println(dashes);
            out.print(sortedLines(lines1));
            out.println(dashes);
            out.print(sortedLines(lines2));
            out.println(dashes);
            out.println("sizes: " + sortedLines(lines1).length() +
                        " " + sortedLines(lines2).length());

            fail("Sorted string contents differ");
        }
    }

    private static final Runtime runtime = Runtime.getRuntime();

    private static final String[] winEnvCommand = {"cmd.exe", "/d", "/c", "set"};

    private static String winEnvFilter(String env) {
        return env.replaceAll("\r", "")
            .replaceAll("(?m)^(?:COMSPEC|PROMPT|PATHEXT)=.*\n","");
    }

    private static String unixEnvProg() {
        return new File("/usr/bin/env").canExecute() ? "/usr/bin/env"
            : "/bin/env";
    }

    private static String nativeEnv(String[] env) {
        try {
            if (Windows.is()) {
                return winEnvFilter
                    (commandOutput(runtime.exec(winEnvCommand, env)));
            } else {
                return commandOutput(runtime.exec(unixEnvProg(), env));
            }
        } catch (Throwable t) { throw new Error(t); }
    }

    private static String nativeEnv(ProcessBuilder pb) {
        try {
            if (Windows.is()) {
                pb.command(winEnvCommand);
                return winEnvFilter(commandOutput(pb));
            } else {
                pb.command(new String[]{unixEnvProg()});
                return commandOutput(pb);
            }
        } catch (Throwable t) { throw new Error(t); }
    }

    private static void checkSizes(Map<String,String> environ, int size) {
        try {
            equal(size, environ.size());
            equal(size, environ.entrySet().size());
            equal(size, environ.keySet().size());
            equal(size, environ.values().size());

            boolean isEmpty = (size == 0);
            equal(isEmpty, environ.isEmpty());
            equal(isEmpty, environ.entrySet().isEmpty());
            equal(isEmpty, environ.keySet().isEmpty());
            equal(isEmpty, environ.values().isEmpty());
        } catch (Throwable t) { unexpected(t); }
    }

    private interface EnvironmentFrobber {
        void doIt(Map<String,String> environ);
    }

    private static void testVariableDeleter(EnvironmentFrobber fooDeleter) {
        try {
            Map<String,String> environ = new ProcessBuilder().environment();
            environ.put("Foo", "BAAR");
            fooDeleter.doIt(environ);
            equal(environ.get("Foo"), null);
            equal(environ.remove("Foo"), null);
        } catch (Throwable t) { unexpected(t); }
    }

    private static void testVariableAdder(EnvironmentFrobber fooAdder) {
        try {
            Map<String,String> environ = new ProcessBuilder().environment();
            environ.remove("Foo");
            fooAdder.doIt(environ);
            equal(environ.get("Foo"), "Bahrein");
        } catch (Throwable t) { unexpected(t); }
    }

    private static void testVariableModifier(EnvironmentFrobber fooModifier) {
        try {
            Map<String,String> environ = new ProcessBuilder().environment();
            environ.put("Foo","OldValue");
            fooModifier.doIt(environ);
            equal(environ.get("Foo"), "NewValue");
        } catch (Throwable t) { unexpected(t); }
    }

    private static void printUTF8(String s) throws IOException {
        out.write(s.getBytes("UTF-8"));
    }

    private static String getenvAsString(Map<String,String> environment) {
        StringBuilder sb = new StringBuilder();
        environment = new TreeMap<>(environment);
        for (Map.Entry<String,String> e : environment.entrySet())
            // Ignore magic environment variables added by the launcher
            if (! e.getKey().equals("LD_LIBRARY_PATH"))
                sb.append(e.getKey())
                    .append('=')
                    .append(e.getValue())
                    .append(',');
        return sb.toString();
    }

    static void print4095(OutputStream s, byte b) throws Throwable {
        byte[] bytes = new byte[4095];
        Arrays.fill(bytes, b);
        s.write(bytes);         // Might hang!
    }

    static void checkPermissionDenied(ProcessBuilder pb) {
        try {
            pb.start();
            fail("Expected IOException not thrown");
        } catch (IOException e) {
            String m = e.getMessage();
            if (EnglishUnix.is() &&
                !matches(m, PERMISSION_DENIED_ERROR_MSG))
                unexpected(e);
            if (matches(m, SPAWNHELPER_FAILURE_MSG))
                unexpected(e);
        } catch (Throwable t) { unexpected(t); }
    }

    public static class JavaChild {
        public static void main(String args[]) throws Throwable {
            String action = args[0];
            if (action.equals("sleep")) {
                Thread.sleep(10 * 60 * 1000L);
            } else if (action.equals("pid")) {
                System.out.println(ProcessHandle.current().pid());
            } else if (action.equals("testIO")) {
                String expected = "standard input";
                char[] buf = new char[expected.length()+1];
                int n = new InputStreamReader(System.in).read(buf,0,buf.length);
                if (n != expected.length())
                    System.exit(5);
                if (! new String(buf,0,n).equals(expected))
                    System.exit(5);
                System.err.print("standard error");
                System.out.print("standard output");
            } else if (action.equals("testInheritIO")
                    || action.equals("testRedirectInherit")) {
                List<String> childArgs = new ArrayList<String>(javaChildArgs);
                childArgs.add("testIO");
                ProcessBuilder pb = new ProcessBuilder(childArgs);
                if (action.equals("testInheritIO"))
                    pb.inheritIO();
                else
                    redirectIO(pb, INHERIT, INHERIT, INHERIT);
                ProcessResults r = run(pb);
                if (! r.out().equals(""))
                    System.exit(7);
                if (! r.err().equals(""))
                    System.exit(8);
                if (r.exitValue() != 0)
                    System.exit(9);
            } else if (action.equals("System.getenv(String)")) {
                String val = System.getenv(args[1]);
                printUTF8(val == null ? "null" : val);
            } else if (action.equals("System.getenv(\\u1234)")) {
                String val = System.getenv("\u1234");
                printUTF8(val == null ? "null" : val);
            } else if (action.equals("System.getenv()")) {
                printUTF8(getenvAsString(System.getenv()));
            } else if (action.equals("ArrayOOME")) {
                Object dummy;
                switch(new Random().nextInt(3)) {
                case 0: dummy = new Integer[Integer.MAX_VALUE]; break;
                case 1: dummy = new double[Integer.MAX_VALUE];  break;
                case 2: dummy = new byte[Integer.MAX_VALUE][];  break;
                default: throw new InternalError();
                }
            } else if (action.equals("pwd")) {
                printUTF8(new File(System.getProperty("user.dir"))
                          .getCanonicalPath());
            } else if (action.equals("print4095")) {
                print4095(System.out, (byte) '!');
                print4095(System.err, (byte) 'E');
                System.exit(5);
            } else if (action.equals("OutErr")) {
                // You might think the system streams would be
                // buffered, and in fact they are implemented using
                // BufferedOutputStream, but each and every print
                // causes immediate operating system I/O.
                System.out.print("out");
                System.err.print("err");
                System.out.print("out");
                System.err.print("err");
            } else if (action.equals("null PATH")) {
                equal(System.getenv("PATH"), null);
                check(new File("/bin/true").exists());
                check(new File("/bin/false").exists());
                ProcessBuilder pb1 = new ProcessBuilder();
                ProcessBuilder pb2 = new ProcessBuilder();
                pb2.environment().put("PATH", "anyOldPathIgnoredAnyways");
                ProcessResults r;

                for (final ProcessBuilder pb :
                         new ProcessBuilder[] {pb1, pb2}) {
                    pb.command("true");
                    equal(run(pb).exitValue(), True.exitValue());

                    pb.command("false");
                    equal(run(pb).exitValue(), False.exitValue());
                }

                if (failed != 0) throw new Error("null PATH");
            } else if (action.equals("PATH search algorithm")) {
                equal(System.getenv("PATH"), "dir1:dir2:");
                check(new File(TrueExe.path()).exists());
                check(new File(FalseExe.path()).exists());
                String[] cmd = {"prog"};
                ProcessBuilder pb1 = new ProcessBuilder(cmd);
                ProcessBuilder pb2 = new ProcessBuilder(cmd);
                ProcessBuilder pb3 = new ProcessBuilder(cmd);
                pb2.environment().put("PATH", "anyOldPathIgnoredAnyways");
                pb3.environment().remove("PATH");

                for (final ProcessBuilder pb :
                         new ProcessBuilder[] {pb1, pb2, pb3}) {
                    try {
                        // Not on PATH at all; directories don't exist
                        try {
                            pb.start();
                            fail("Expected IOException not thrown");
                        } catch (IOException e) {
                            String m = e.getMessage();
                            if (EnglishUnix.is() &&
                                !matches(m, NO_SUCH_FILE_ERROR_MSG))
                                unexpected(e);
                            if (matches(m, SPAWNHELPER_FAILURE_MSG))
                                unexpected(e);
                        } catch (Throwable t) { unexpected(t); }

                        // Not on PATH at all; directories exist
                        new File("dir1").mkdirs();
                        new File("dir2").mkdirs();
                        try {
                            pb.start();
                            fail("Expected IOException not thrown");
                        } catch (IOException e) {
                            String m = e.getMessage();
                            if (EnglishUnix.is() &&
                                !matches(m, NO_SUCH_FILE_ERROR_MSG))
                                unexpected(e);
                            if (matches(m, SPAWNHELPER_FAILURE_MSG))
                                unexpected(e);
                        } catch (Throwable t) { unexpected(t); }

                        // Can't execute a directory -- permission denied
                        // Report EACCES errno
                        new File("dir1/prog").mkdirs();
                        checkPermissionDenied(pb);

                        // continue searching if EACCES
                        copy(TrueExe.path(), "dir2/prog");
                        equal(run(pb).exitValue(), True.exitValue());
                        new File("dir1/prog").delete();
                        new File("dir2/prog").delete();

                        new File("dir2/prog").mkdirs();
                        copy(TrueExe.path(), "dir1/prog");
                        equal(run(pb).exitValue(), True.exitValue());

                        // Check empty PATH component means current directory.
                        //
                        // While we're here, let's test different kinds of
                        // Unix executables, and PATH vs explicit searching.
                        new File("dir1/prog").delete();
                        new File("dir2/prog").delete();
                        for (String[] command :
                                 new String[][] {
                                     new String[] {"./prog"},
                                     cmd}) {
                            pb.command(command);
                            File prog = new File("./prog");
                            // "Normal" binaries
                            copy(TrueExe.path(), "./prog");
                            equal(run(pb).exitValue(),
                                  True.exitValue());
                            copy(FalseExe.path(), "./prog");
                            equal(run(pb).exitValue(),
                                  False.exitValue());
                            prog.delete();
                            // Interpreter scripts with #!
                            setFileContents(prog, "#!/bin/true\n");
                            prog.setExecutable(true);
                            equal(run(pb).exitValue(),
                                  True.exitValue());
                            prog.delete();
                            setFileContents(prog, "#!/bin/false\n");
                            prog.setExecutable(true);
                            equal(run(pb).exitValue(),
                                  False.exitValue());
                            // Traditional shell scripts without #!
                            if (!(Platform.isLinux() && Platform.isMusl())) {
                                setFileContents(prog, "exec /bin/true\n");
                                prog.setExecutable(true);
                                equal(run(pb).exitValue(), True.exitValue());
                                prog.delete();
                                setFileContents(prog, "exec /bin/false\n");
                                prog.setExecutable(true);
                                equal(run(pb).exitValue(), False.exitValue());
                            }
                            prog.delete();
                        }

                        // Test Unix interpreter scripts
                        File dir1Prog = new File("dir1/prog");
                        dir1Prog.delete();
                        pb.command(new String[] {"prog", "world"});
                        setFileContents(dir1Prog, "#!/bin/echo hello\n");
                        checkPermissionDenied(pb);
                        dir1Prog.setExecutable(true);
                        equal(run(pb).out(), "hello dir1/prog world\n");
                        equal(run(pb).exitValue(), True.exitValue());
                        dir1Prog.delete();
                        pb.command(cmd);

                        // Test traditional shell scripts without #!
                        if (!(Platform.isLinux() && Platform.isMusl())) {
                            setFileContents(dir1Prog, "/bin/echo \"$@\"\n");
                            pb.command(new String[] {"prog", "hello", "world"});
                            checkPermissionDenied(pb);
                            dir1Prog.setExecutable(true);
                            equal(run(pb).out(), "hello world\n");
                            equal(run(pb).exitValue(), True.exitValue());
                            dir1Prog.delete();
                            pb.command(cmd);
                        }

                        // If prog found on both parent and child's PATH,
                        // parent's is used.
                        new File("dir1/prog").delete();
                        new File("dir2/prog").delete();
                        new File("prog").delete();
                        new File("dir3").mkdirs();
                        copy(TrueExe.path(), "dir1/prog");
                        copy(FalseExe.path(), "dir3/prog");
                        pb.environment().put("PATH","dir3");
                        equal(run(pb).exitValue(), True.exitValue());
                        copy(TrueExe.path(), "dir3/prog");
                        copy(FalseExe.path(), "dir1/prog");
                        equal(run(pb).exitValue(), False.exitValue());

                    } finally {
                        // cleanup
                        new File("dir1/prog").delete();
                        new File("dir2/prog").delete();
                        new File("dir3/prog").delete();
                        new File("dir1").delete();
                        new File("dir2").delete();
                        new File("dir3").delete();
                        new File("prog").delete();
                    }
                }

                if (failed != 0) throw new Error("PATH search algorithm");
            }
            else throw new Error("JavaChild invocation error");
        }
    }

    private static void copy(String src, String dst) throws IOException {
        Files.copy(Paths.get(src), Paths.get(dst),
                   StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
    }

    private static String javaChildOutput(ProcessBuilder pb, String...args) {
        List<String> list = new ArrayList<String>(javaChildArgs);
        for (String arg : args)
            list.add(arg);
        pb.command(list);
        return commandOutput(pb);
    }

    private static String getenvInChild(ProcessBuilder pb) {
        return javaChildOutput(pb, "System.getenv()");
    }

    private static String getenvInChild1234(ProcessBuilder pb) {
        return javaChildOutput(pb, "System.getenv(\\u1234)");
    }

    private static String getenvInChild(ProcessBuilder pb, String name) {
        return javaChildOutput(pb, "System.getenv(String)", name);
    }

    private static String pwdInChild(ProcessBuilder pb) {
        return javaChildOutput(pb, "pwd");
    }

    private static final String javaExe =
        System.getProperty("java.home") +
        File.separator + "bin" + File.separator + "java";

    private static final String classpath =
        System.getProperty("java.class.path");

    private static final List<String> javaChildArgs =
        Arrays.asList(javaExe,
                      "-XX:+DisplayVMOutputToStderr",
                      "-classpath", absolutifyPath(classpath),
                      "Basic$JavaChild");

    private static void testEncoding(String encoding, String tested) {
        try {
            // If round trip conversion works, should be able to set env vars
            // correctly in child.
            String jnuEncoding = System.getProperty("sun.jnu.encoding");
            Charset cs = jnuEncoding != null
                ? Charset.forName(jnuEncoding, Charset.defaultCharset())
                : Charset.defaultCharset();
            if (new String(tested.getBytes(cs), cs).equals(tested)) {
                out.println("Testing " + encoding + " environment values");
                ProcessBuilder pb = new ProcessBuilder();
                pb.environment().put("ASCIINAME",tested);
                equal(getenvInChild(pb,"ASCIINAME"), tested);
            }
        } catch (Throwable t) { unexpected(t); }
    }

    static class Windows {
        public static boolean is() { return is; }
        private static final boolean is =
            System.getProperty("os.name").startsWith("Windows");
    }

    static class AIX {
        public static boolean is() { return is; }
        private static final boolean is =
            System.getProperty("os.name").equals("AIX");
    }

    static class Unix {
        public static boolean is() { return is; }
        private static final boolean is =
            (! Windows.is() &&
             new File("/bin/sh").exists() &&
             new File("/bin/true").exists() &&
             new File("/bin/false").exists());
    }

    static class UnicodeOS {
        public static boolean is() { return is; }
        private static final String osName = System.getProperty("os.name");
        private static final boolean is =
            // MacOS X would probably also qualify
            osName.startsWith("Windows")   &&
            ! osName.startsWith("Windows 9") &&
            ! osName.equals("Windows Me");
    }

    static class MacOSX {
        public static boolean is() { return is; }
        private static final String osName = System.getProperty("os.name");
        private static final boolean is = osName.contains("OS X");
    }

    static class True {
        public static int exitValue() { return 0; }
    }

    private static class False {
        public static int exitValue() { return exitValue; }
        private static final int exitValue = exitValue0();
        private static int exitValue0() {
            // /bin/false returns an *unspecified* non-zero number.
            try {
                if (! Unix.is())
                    return -1;
                else {
                    int rc = new ProcessBuilder("/bin/false")
                        .start().waitFor();
                    check(rc != 0);
                    return rc;
                }
            } catch (Throwable t) { unexpected(t); return -1; }
        }
    }

    // On Alpine Linux, /bin/true and /bin/false are just links to /bin/busybox.
    // Some tests copy /bin/true and /bin/false to files with a different filename.
    // However, copying the busbox executable into a file with a different name
    // won't result in the expected return codes. As workaround, we create
    // executable files that can be copied and produce the expected return
    // values.

    private static class TrueExe {
        public static String path() { return path; }
        private static final String path = path0();
        private static String path0(){
            if (!Files.isSymbolicLink(Paths.get("/bin/true"))) {
                return "/bin/true";
            } else {
                File trueExe = new File("true");
                setFileContents(trueExe, "#!/bin/true\n");
                trueExe.setExecutable(true);
                return trueExe.getAbsolutePath();
            }
        }
    }

    private static class FalseExe {
        public static String path() { return path; }
        private static final String path = path0();
        private static String path0(){
            if (!Files.isSymbolicLink(Paths.get("/bin/false"))) {
                return "/bin/false";
            } else {
                File falseExe = new File("false");
                setFileContents(falseExe, "#!/bin/false\n");
                falseExe.setExecutable(true);
                return falseExe.getAbsolutePath();
            }
        }
    }

    static class EnglishUnix {
        private static final Boolean is =
            (! Windows.is() && isEnglish("LANG") && isEnglish("LC_ALL"));

        private static boolean isEnglish(String envvar) {
            String val = getenv(envvar);
            return (val == null) || val.matches("en.*") || val.matches("C");
        }

        /** Returns true if we can expect English OS error strings */
        static boolean is() { return is; }
    }

    static class DelegatingProcess extends Process {
        final Process p;

        DelegatingProcess(Process p) {
            this.p = p;
        }

        @Override
        public void destroy() {
            p.destroy();
        }

        @Override
        public int exitValue() {
            return p.exitValue();
        }

        @Override
        public int waitFor() throws InterruptedException {
            return p.waitFor();
        }

        @Override
        public OutputStream getOutputStream() {
            return p.getOutputStream();
        }

        @Override
        public InputStream getInputStream() {
            return p.getInputStream();
        }

        @Override
        public InputStream getErrorStream() {
            return p.getErrorStream();
        }
    }

    private static boolean matches(String str, String regex) {
        return Pattern.compile(regex).matcher(str).find();
    }

    // Return the string with the matching regex removed
    private static String matchAndRemove(String str, String regex) {
        return Pattern.compile(regex)
                .matcher(str)
                .replaceAll("");
    }

    /* Only used for Mac OS X --
     * Mac OS X (may) add the variables: __CF_USER_TEXT_ENCODING, JAVA_MAIN_CLASS_<pid>,
     * and TMPDIR.
     * Remove them from the list of env variables
     */
    private static String removeMacExpectedVars(String vars) {
        // Check for __CF_USER_TEXT_ENCODING
        String cleanedVars = matchAndRemove(vars,
                "__CF_USER_TEXT_ENCODING=" + cfUserTextEncoding + ",");
        // Check for JAVA_MAIN_CLASS_<pid>
        cleanedVars = matchAndRemove(cleanedVars,
                "JAVA_MAIN_CLASS_\\d+=Basic.JavaChild,");
        // Check and remove TMPDIR
        cleanedVars = matchAndRemove(cleanedVars,
                "TMPDIR=[^,]*,");
        return cleanedVars;
    }

    /* Only used for AIX --
     * AIX adds the variable AIXTHREAD_GUARDPAGES=0 to the environment.
     * Remove it from the list of env variables
     */
    private static String removeAixExpectedVars(String vars) {
        return vars.replace("AIXTHREAD_GUARDPAGES=0,", "");
    }

    private static String sortByLinesWindowsly(String text) {
        String[] lines = text.split("\n");
        Arrays.sort(lines, new WindowsComparator());
        StringBuilder sb = new StringBuilder();
        for (String line : lines)
            sb.append(line).append("\n");
        return sb.toString();
    }

    private static void checkMapSanity(Map<String,String> map) {
        try {
            Set<String> keySet = map.keySet();
            Collection<String> values = map.values();
            Set<Map.Entry<String,String>> entrySet = map.entrySet();

            equal(entrySet.size(), keySet.size());
            equal(entrySet.size(), values.size());

            StringBuilder s1 = new StringBuilder();
            for (Map.Entry<String,String> e : entrySet)
                s1.append(e.getKey() + "=" + e.getValue() + "\n");

            StringBuilder s2 = new StringBuilder();
            for (String var : keySet)
                s2.append(var + "=" + map.get(var) + "\n");

            equal(s1.toString(), s2.toString());

            Iterator<String> kIter = keySet.iterator();
            Iterator<String> vIter = values.iterator();
            Iterator<Map.Entry<String,String>> eIter = entrySet.iterator();

            while (eIter.hasNext()) {
                Map.Entry<String,String> entry = eIter.next();
                String key   = kIter.next();
                String value = vIter.next();
                check(entrySet.contains(entry));
                check(keySet.contains(key));
                check(values.contains(value));
                check(map.containsKey(key));
                check(map.containsValue(value));
                equal(entry.getKey(), key);
                equal(entry.getValue(), value);
            }
            check(!kIter.hasNext() &&
                    !vIter.hasNext());

        } catch (Throwable t) { unexpected(t); }
    }

    private static void checkMapEquality(Map<String,String> map1,
                                         Map<String,String> map2) {
        try {
            equal(map1.size(), map2.size());
            equal(map1.isEmpty(), map2.isEmpty());
            for (String key : map1.keySet()) {
                equal(map1.get(key), map2.get(key));
                check(map2.keySet().contains(key));
            }
            equal(map1, map2);
            equal(map2, map1);
            equal(map1.entrySet(), map2.entrySet());
            equal(map2.entrySet(), map1.entrySet());
            equal(map1.keySet(), map2.keySet());
            equal(map2.keySet(), map1.keySet());

            equal(map1.hashCode(), map2.hashCode());
            equal(map1.entrySet().hashCode(), map2.entrySet().hashCode());
            equal(map1.keySet().hashCode(), map2.keySet().hashCode());
        } catch (Throwable t) { unexpected(t); }
    }

    static void checkRedirects(ProcessBuilder pb,
                               Redirect in, Redirect out, Redirect err) {
        equal(pb.redirectInput(), in);
        equal(pb.redirectOutput(), out);
        equal(pb.redirectError(), err);
    }

    static void redirectIO(ProcessBuilder pb,
                           Redirect in, Redirect out, Redirect err) {
        pb.redirectInput(in);
        pb.redirectOutput(out);
        pb.redirectError(err);
    }

    static void setFileContents(File file, String contents) {
        try {
            Writer w = new FileWriter(file);
            w.write(contents);
            w.close();
        } catch (Throwable t) { unexpected(t); }
    }

    static String fileContents(File file) {
        try {
            Reader r = new FileReader(file);
            StringBuilder sb = new StringBuilder();
            char[] buffer = new char[1024];
            int n;
            while ((n = r.read(buffer)) != -1)
                sb.append(buffer,0,n);
            r.close();
            return new String(sb);
        } catch (Throwable t) { unexpected(t); return ""; }
    }

    @SuppressWarnings("removal")
    static void testIORedirection() throws Throwable {
        final File ifile = new File("ifile");
        final File ofile = new File("ofile");
        final File efile = new File("efile");
        ifile.delete();
        ofile.delete();
        efile.delete();

        //----------------------------------------------------------------
        // Check mutual inequality of different types of Redirect
        //----------------------------------------------------------------
        Redirect[] redirects =
            { PIPE,
              INHERIT,
              DISCARD,
              Redirect.from(ifile),
              Redirect.to(ifile),
              Redirect.appendTo(ifile),
              Redirect.from(ofile),
              Redirect.to(ofile),
              Redirect.appendTo(ofile),
            };
        for (int i = 0; i < redirects.length; i++)
            for (int j = 0; j < redirects.length; j++)
                equal(redirects[i].equals(redirects[j]), (i == j));

        //----------------------------------------------------------------
        // Check basic properties of different types of Redirect
        //----------------------------------------------------------------
        equal(PIPE.type(), Redirect.Type.PIPE);
        equal(PIPE.toString(), "PIPE");
        equal(PIPE.file(), null);

        equal(INHERIT.type(), Redirect.Type.INHERIT);
        equal(INHERIT.toString(), "INHERIT");
        equal(INHERIT.file(), null);

        equal(DISCARD.type(), Redirect.Type.WRITE);
        equal(DISCARD.toString(), "WRITE");
        equal(DISCARD.file(), new File((Windows.is() ? "NUL" : "/dev/null")));

        equal(Redirect.from(ifile).type(), Redirect.Type.READ);
        equal(Redirect.from(ifile).toString(),
              "redirect to read from file \"ifile\"");
        equal(Redirect.from(ifile).file(), ifile);
        equal(Redirect.from(ifile),
              Redirect.from(ifile));
        equal(Redirect.from(ifile).hashCode(),
              Redirect.from(ifile).hashCode());

        equal(Redirect.to(ofile).type(), Redirect.Type.WRITE);
        equal(Redirect.to(ofile).toString(),
              "redirect to write to file \"ofile\"");
        equal(Redirect.to(ofile).file(), ofile);
        equal(Redirect.to(ofile),
              Redirect.to(ofile));
        equal(Redirect.to(ofile).hashCode(),
              Redirect.to(ofile).hashCode());

        equal(Redirect.appendTo(ofile).type(), Redirect.Type.APPEND);
        equal(Redirect.appendTo(efile).toString(),
              "redirect to append to file \"efile\"");
        equal(Redirect.appendTo(efile).file(), efile);
        equal(Redirect.appendTo(efile),
              Redirect.appendTo(efile));
        equal(Redirect.appendTo(efile).hashCode(),
              Redirect.appendTo(efile).hashCode());

        //----------------------------------------------------------------
        // Check initial values of redirects
        //----------------------------------------------------------------
        List<String> childArgs = new ArrayList<String>(javaChildArgs);
        childArgs.add("testIO");
        final ProcessBuilder pb = new ProcessBuilder(childArgs);
        checkRedirects(pb, PIPE, PIPE, PIPE);

        //----------------------------------------------------------------
        // Check inheritIO
        //----------------------------------------------------------------
        pb.inheritIO();
        checkRedirects(pb, INHERIT, INHERIT, INHERIT);

        //----------------------------------------------------------------
        // Check DISCARD for stdout,stderr
        //----------------------------------------------------------------
        redirectIO(pb, INHERIT, DISCARD, DISCARD);
        checkRedirects(pb, INHERIT, DISCARD, DISCARD);

        //----------------------------------------------------------------
        // Check setters and getters agree
        //----------------------------------------------------------------
        pb.redirectInput(ifile);
        equal(pb.redirectInput().file(), ifile);
        equal(pb.redirectInput(), Redirect.from(ifile));

        pb.redirectOutput(ofile);
        equal(pb.redirectOutput().file(), ofile);
        equal(pb.redirectOutput(), Redirect.to(ofile));

        pb.redirectError(efile);
        equal(pb.redirectError().file(), efile);
        equal(pb.redirectError(), Redirect.to(efile));

        THROWS(IllegalArgumentException.class,
               () -> pb.redirectInput(Redirect.to(ofile)),
               () -> pb.redirectOutput(Redirect.from(ifile)),
               () -> pb.redirectError(Redirect.from(ifile)),
               () -> pb.redirectInput(DISCARD));

        THROWS(NullPointerException.class,
                () -> pb.redirectInput((File)null),
                () -> pb.redirectOutput((File)null),
                () -> pb.redirectError((File)null),
                () -> pb.redirectInput((Redirect)null),
                () -> pb.redirectOutput((Redirect)null),
                () -> pb.redirectError((Redirect)null));

        THROWS(IOException.class,
               // Input file does not exist
               () -> pb.start());
        setFileContents(ifile, "standard input");

        //----------------------------------------------------------------
        // Writing to non-existent files
        //----------------------------------------------------------------
        {
            ProcessResults r = run(pb);
            equal(r.exitValue(), 0);
            equal(fileContents(ofile), "standard output");
            equal(fileContents(efile), "standard error");
            equal(r.out(), "");
            equal(r.err(), "");
            ofile.delete();
            efile.delete();
        }

        //----------------------------------------------------------------
        // Both redirectErrorStream + redirectError
        //----------------------------------------------------------------
        {
            pb.redirectErrorStream(true);
            ProcessResults r = run(pb);
            equal(r.exitValue(), 0);
            equal(fileContents(ofile),
                    "standard error" + "standard output");
            equal(fileContents(efile), "");
            equal(r.out(), "");
            equal(r.err(), "");
            ofile.delete();
            efile.delete();
        }

        //----------------------------------------------------------------
        // Appending to existing files
        //----------------------------------------------------------------
        {
            setFileContents(ofile, "ofile-contents");
            setFileContents(efile, "efile-contents");
            pb.redirectOutput(Redirect.appendTo(ofile));
            pb.redirectError(Redirect.appendTo(efile));
            pb.redirectErrorStream(false);
            ProcessResults r = run(pb);
            equal(r.exitValue(), 0);
            equal(fileContents(ofile),
                  "ofile-contents" + "standard output");
            equal(fileContents(efile),
                  "efile-contents" + "standard error");
            equal(r.out(), "");
            equal(r.err(), "");
            ofile.delete();
            efile.delete();
        }

        //----------------------------------------------------------------
        // Replacing existing files
        //----------------------------------------------------------------
        {
            setFileContents(ofile, "ofile-contents");
            setFileContents(efile, "efile-contents");
            pb.redirectOutput(ofile);
            pb.redirectError(Redirect.to(efile));
            ProcessResults r = run(pb);
            equal(r.exitValue(), 0);
            equal(fileContents(ofile), "standard output");
            equal(fileContents(efile), "standard error");
            equal(r.out(), "");
            equal(r.err(), "");
            ofile.delete();
            efile.delete();
        }

        //----------------------------------------------------------------
        // Appending twice to the same file?
        //----------------------------------------------------------------
        {
            setFileContents(ofile, "ofile-contents");
            setFileContents(efile, "efile-contents");
            Redirect appender = Redirect.appendTo(ofile);
            pb.redirectOutput(appender);
            pb.redirectError(appender);
            ProcessResults r = run(pb);
            equal(r.exitValue(), 0);
            equal(fileContents(ofile),
                  "ofile-contents" +
                  "standard error" +
                  "standard output");
            equal(fileContents(efile), "efile-contents");
            equal(r.out(), "");
            equal(r.err(), "");
            ifile.delete();
            ofile.delete();
            efile.delete();
        }

        //----------------------------------------------------------------
        // DISCARDing output
        //----------------------------------------------------------------
        {
            setFileContents(ifile, "standard input");
            pb.redirectOutput(DISCARD);
            pb.redirectError(DISCARD);
            ProcessResults r = run(pb);
            equal(r.exitValue(), 0);
            equal(r.out(), "");
            equal(r.err(), "");
        }

        //----------------------------------------------------------------
        // DISCARDing output and redirecting error
        //----------------------------------------------------------------
        {
            setFileContents(ifile, "standard input");
            setFileContents(ofile, "ofile-contents");
            setFileContents(efile, "efile-contents");
            pb.redirectOutput(DISCARD);
            pb.redirectError(efile);
            ProcessResults r = run(pb);
            equal(r.exitValue(), 0);
            equal(fileContents(ofile), "ofile-contents");
            equal(fileContents(efile), "standard error");
            equal(r.out(), "");
            equal(r.err(), "");
            ofile.delete();
            efile.delete();
        }

        //----------------------------------------------------------------
        // DISCARDing error and redirecting output
        //----------------------------------------------------------------
        {
            setFileContents(ifile, "standard input");
            setFileContents(ofile, "ofile-contents");
            setFileContents(efile, "efile-contents");
            pb.redirectOutput(ofile);
            pb.redirectError(DISCARD);
            ProcessResults r = run(pb);
            equal(r.exitValue(), 0);
            equal(fileContents(ofile), "standard output");
            equal(fileContents(efile), "efile-contents");
            equal(r.out(), "");
            equal(r.err(), "");
            ofile.delete();
            efile.delete();
        }

        //----------------------------------------------------------------
        // DISCARDing output and merging error into output
        //----------------------------------------------------------------
        {
            setFileContents(ifile, "standard input");
            setFileContents(ofile, "ofile-contents");
            setFileContents(efile, "efile-contents");
            pb.redirectOutput(DISCARD);
            pb.redirectErrorStream(true);
            pb.redirectError(efile);
            ProcessResults r = run(pb);
            equal(r.exitValue(), 0);
            equal(fileContents(ofile), "ofile-contents");   // untouched
            equal(fileContents(efile), "");                 // empty
            equal(r.out(), "");
            equal(r.err(), "");
            ifile.delete();
            ofile.delete();
            efile.delete();
            pb.redirectErrorStream(false);                  // reset for next test
        }

        //----------------------------------------------------------------
        // Testing INHERIT is harder.
        // Note that this requires __FOUR__ nested JVMs involved in one test,
        // if you count the harness JVM.
        //----------------------------------------------------------------
        for (String testName : new String[] { "testInheritIO", "testRedirectInherit" } ) {
            redirectIO(pb, PIPE, PIPE, PIPE);
            List<String> command = pb.command();
            command.set(command.size() - 1, testName);
            Process p = pb.start();
            new PrintStream(p.getOutputStream()).print("standard input");
            p.getOutputStream().close();
            ProcessResults r = run(p);
            equal(r.exitValue(), 0);
            equal(r.out(), "standard output");
            equal(r.err(), "standard error");
        }
    }

    static void checkProcessPid() {
        ProcessBuilder pb = new ProcessBuilder();
        List<String> list = new ArrayList<String>(javaChildArgs);
        list.add("pid");
        pb.command(list);
        try {
            Process p = pb.start();
            String s = commandOutput(p);
            long actualPid = Long.valueOf(s.trim());
            long expectedPid = p.pid();
            equal(actualPid, expectedPid);
        } catch (Throwable t) {
            unexpected(t);
        }


        // Test the default implementation of Process.getPid
        DelegatingProcess p = new DelegatingProcess(null);
        THROWS(UnsupportedOperationException.class,
                () -> p.pid(),
                () -> p.toHandle(),
                () -> p.supportsNormalTermination(),
                () -> p.children(),
                () -> p.descendants());

    }

    @SuppressWarnings("removal")
    private static void realMain(String[] args) throws Throwable {
        if (Windows.is())
            System.out.println("This appears to be a Windows system.");
        if (Unix.is())
            System.out.println("This appears to be a Unix system.");
        if (UnicodeOS.is())
            System.out.println("This appears to be a Unicode-based OS.");

        try { testIORedirection(); }
        catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Basic tests for getPid()
        //----------------------------------------------------------------
        checkProcessPid();

        //----------------------------------------------------------------
        // Basic tests for setting, replacing and deleting envvars
        //----------------------------------------------------------------
        try {
            ProcessBuilder pb = new ProcessBuilder();
            Map<String,String> environ = pb.environment();

            // New env var
            environ.put("QUUX", "BAR");
            equal(environ.get("QUUX"), "BAR");
            equal(getenvInChild(pb,"QUUX"), "BAR");

            // Modify env var
            environ.put("QUUX","bear");
            equal(environ.get("QUUX"), "bear");
            equal(getenvInChild(pb,"QUUX"), "bear");
            checkMapSanity(environ);

            // Remove env var
            environ.remove("QUUX");
            equal(environ.get("QUUX"), null);
            equal(getenvInChild(pb,"QUUX"), "null");
            checkMapSanity(environ);

            // Remove non-existent env var
            environ.remove("QUUX");
            equal(environ.get("QUUX"), null);
            equal(getenvInChild(pb,"QUUX"), "null");
            checkMapSanity(environ);
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Pass Empty environment to child
        //----------------------------------------------------------------
        try {
            ProcessBuilder pb = new ProcessBuilder();
            pb.environment().clear();
            String expected = Windows.is() ? "SystemRoot="+systemRoot+",": "";
            expected = AIX.is() ? "LIBPATH="+libpath+",": expected;
            if (Windows.is()) {
                pb.environment().put("SystemRoot", systemRoot);
            }
            if (AIX.is()) {
                pb.environment().put("LIBPATH", libpath);
            }
            String result = getenvInChild(pb);
            if (MacOSX.is()) {
                result = removeMacExpectedVars(result);
            }
            if (AIX.is()) {
                result = removeAixExpectedVars(result);
            }
            equal(result, expected);
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // System.getenv() is read-only.
        //----------------------------------------------------------------
        THROWS(UnsupportedOperationException.class,
               () -> getenv().put("FOO","BAR"),
               () -> getenv().remove("PATH"),
               () -> getenv().keySet().remove("PATH"),
               () -> getenv().values().remove("someValue"));

        try {
            Collection<Map.Entry<String,String>> c = getenv().entrySet();
            if (! c.isEmpty())
                try {
                    c.iterator().next().setValue("foo");
                    fail("Expected UnsupportedOperationException not thrown");
                } catch (UnsupportedOperationException e) {} // OK
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // System.getenv() always returns the same object in our implementation.
        //----------------------------------------------------------------
        try {
            check(System.getenv() == System.getenv());
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // You can't create an env var name containing "=",
        // or an env var name or value containing NUL.
        //----------------------------------------------------------------
        {
            final Map<String,String> m = new ProcessBuilder().environment();
            THROWS(IllegalArgumentException.class,
                   () -> m.put("FOO=","BAR"),
                   () -> m.put("FOO\u0000","BAR"),
                   () -> m.put("FOO","BAR\u0000"));
        }

        //----------------------------------------------------------------
        // Commands must never be null.
        //----------------------------------------------------------------
        THROWS(NullPointerException.class,
               () -> new ProcessBuilder((List<String>)null),
               () -> new ProcessBuilder().command((List<String>)null));

        //----------------------------------------------------------------
        // Put in a command; get the same one back out.
        //----------------------------------------------------------------
        try {
            List<String> command = new ArrayList<String>();
            ProcessBuilder pb = new ProcessBuilder(command);
            check(pb.command() == command);
            List<String> command2 = new ArrayList<String>(2);
            command2.add("foo");
            command2.add("bar");
            pb.command(command2);
            check(pb.command() == command2);
            pb.command("foo", "bar");
            check(pb.command() != command2 && pb.command().equals(command2));
            pb.command(command2);
            command2.add("baz");
            equal(pb.command().get(2), "baz");
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Commands must contain at least one element.
        //----------------------------------------------------------------
        THROWS(IndexOutOfBoundsException.class,
               () -> new ProcessBuilder().start(),
               () -> new ProcessBuilder(new ArrayList<String>()).start(),
               () -> Runtime.getRuntime().exec(new String[]{}));

        //----------------------------------------------------------------
        // Commands must not contain null elements at start() time.
        //----------------------------------------------------------------
        THROWS(NullPointerException.class,
               () -> new ProcessBuilder("foo",null,"bar").start(),
               () -> new ProcessBuilder((String)null).start(),
               () -> new ProcessBuilder(new String[]{null}).start(),
               () -> new ProcessBuilder(new String[]{"foo",null,"bar"}).start());

        //----------------------------------------------------------------
        // Command lists are growable.
        //----------------------------------------------------------------
        try {
            new ProcessBuilder().command().add("foo");
            new ProcessBuilder("bar").command().add("foo");
            new ProcessBuilder(new String[]{"1","2"}).command().add("3");
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Nulls in environment updates generate NullPointerException
        //----------------------------------------------------------------
        try {
            final Map<String,String> env = new ProcessBuilder().environment();
            THROWS(NullPointerException.class,
                   () -> env.put("foo",null),
                   () -> env.put(null,"foo"),
                   () -> env.remove(null),
                   () -> { for (Map.Entry<String,String> e : env.entrySet())
                               e.setValue(null);},
                   () -> Runtime.getRuntime().exec(new String[]{"foo"},
                                                   new String[]{null}));
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Non-String types in environment updates generate ClassCastException
        //----------------------------------------------------------------
        try {
            final Map<String,String> env = new ProcessBuilder().environment();
            THROWS(ClassCastException.class,
                   () -> env.remove(TRUE),
                   () -> env.keySet().remove(TRUE),
                   () -> env.values().remove(TRUE),
                   () -> env.entrySet().remove(TRUE));
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Check query operations on environment maps
        //----------------------------------------------------------------
        try {
            List<Map<String,String>> envs =
                new ArrayList<Map<String,String>>(2);
            envs.add(System.getenv());
            envs.add(new ProcessBuilder().environment());
            for (final Map<String,String> env : envs) {
                //----------------------------------------------------------------
                // Nulls in environment queries are forbidden.
                //----------------------------------------------------------------
                THROWS(NullPointerException.class,
                       () -> getenv(null),
                       () -> env.get(null),
                       () -> env.containsKey(null),
                       () -> env.containsValue(null),
                       () -> env.keySet().contains(null),
                       () -> env.values().contains(null));

                //----------------------------------------------------------------
                // Non-String types in environment queries are forbidden.
                //----------------------------------------------------------------
                THROWS(ClassCastException.class,
                       () -> env.get(TRUE),
                       () -> env.containsKey(TRUE),
                       () -> env.containsValue(TRUE),
                       () -> env.keySet().contains(TRUE),
                       () -> env.values().contains(TRUE));

                //----------------------------------------------------------------
                // Illegal String values in environment queries are (grumble) OK
                //----------------------------------------------------------------
                equal(env.get("\u0000"), null);
                check(! env.containsKey("\u0000"));
                check(! env.containsValue("\u0000"));
                check(! env.keySet().contains("\u0000"));
                check(! env.values().contains("\u0000"));
            }

        } catch (Throwable t) { unexpected(t); }

        try {
            final Set<Map.Entry<String,String>> entrySet =
                new ProcessBuilder().environment().entrySet();
            THROWS(NullPointerException.class,
                   () -> entrySet.contains(null));
            THROWS(ClassCastException.class,
                   () -> entrySet.contains(TRUE),
                   () -> entrySet.contains(
                             new SimpleImmutableEntry<Boolean,String>(TRUE,"")));

            check(! entrySet.contains
                  (new SimpleImmutableEntry<String,String>("", "")));
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Put in a directory; get the same one back out.
        //----------------------------------------------------------------
        try {
            ProcessBuilder pb = new ProcessBuilder();
            File foo = new File("foo");
            equal(pb.directory(), null);
            equal(pb.directory(foo).directory(), foo);
            equal(pb.directory(null).directory(), null);
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // If round-trip conversion works, check envvar pass-through to child
        //----------------------------------------------------------------
        try {
            testEncoding("ASCII",   "xyzzy");
            testEncoding("Latin1",  "\u00f1\u00e1");
            testEncoding("Unicode", "\u22f1\u11e1");
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // A surprisingly large number of ways to delete an environment var.
        //----------------------------------------------------------------
        testVariableDeleter(new EnvironmentFrobber() {
                public void doIt(Map<String,String> environ) {
                    environ.remove("Foo");}});

        testVariableDeleter(new EnvironmentFrobber() {
                public void doIt(Map<String,String> environ) {
                    environ.keySet().remove("Foo");}});

        testVariableDeleter(new EnvironmentFrobber() {
                public void doIt(Map<String,String> environ) {
                    environ.values().remove("BAAR");}});

        testVariableDeleter(new EnvironmentFrobber() {
                public void doIt(Map<String,String> environ) {
                    // Legally fabricate a ProcessEnvironment.StringEntry,
                    // even though it's private.
                    Map<String,String> environ2
                        = new ProcessBuilder().environment();
                    environ2.clear();
                    environ2.put("Foo","BAAR");
                    // Subtlety alert.
                    Map.Entry<String,String> e
                        = environ2.entrySet().iterator().next();
                    environ.entrySet().remove(e);}});

        testVariableDeleter(new EnvironmentFrobber() {
                public void doIt(Map<String,String> environ) {
                    Map.Entry<String,String> victim = null;
                    for (Map.Entry<String,String> e : environ.entrySet())
                        if (e.getKey().equals("Foo"))
                            victim = e;
                    if (victim != null)
                        environ.entrySet().remove(victim);}});

        testVariableDeleter(new EnvironmentFrobber() {
                public void doIt(Map<String,String> environ) {
                    Iterator<String> it = environ.keySet().iterator();
                    while (it.hasNext()) {
                        String val = it.next();
                        if (val.equals("Foo"))
                            it.remove();}}});

        testVariableDeleter(new EnvironmentFrobber() {
                public void doIt(Map<String,String> environ) {
                    Iterator<Map.Entry<String,String>> it
                        = environ.entrySet().iterator();
                    while (it.hasNext()) {
                        Map.Entry<String,String> e = it.next();
                        if (e.getKey().equals("Foo"))
                            it.remove();}}});

        testVariableDeleter(new EnvironmentFrobber() {
                public void doIt(Map<String,String> environ) {
                    Iterator<String> it = environ.values().iterator();
                    while (it.hasNext()) {
                        String val = it.next();
                        if (val.equals("BAAR"))
                            it.remove();}}});

        //----------------------------------------------------------------
        // A surprisingly small number of ways to add an environment var.
        //----------------------------------------------------------------
        testVariableAdder(new EnvironmentFrobber() {
                public void doIt(Map<String,String> environ) {
                    environ.put("Foo","Bahrein");}});

        //----------------------------------------------------------------
        // A few ways to modify an environment var.
        //----------------------------------------------------------------
        testVariableModifier(new EnvironmentFrobber() {
                public void doIt(Map<String,String> environ) {
                    environ.put("Foo","NewValue");}});

        testVariableModifier(new EnvironmentFrobber() {
                public void doIt(Map<String,String> environ) {
                    for (Map.Entry<String,String> e : environ.entrySet())
                        if (e.getKey().equals("Foo"))
                            e.setValue("NewValue");}});

        //----------------------------------------------------------------
        // Fiddle with environment sizes
        //----------------------------------------------------------------
        try {
            Map<String,String> environ = new ProcessBuilder().environment();
            int size = environ.size();
            checkSizes(environ, size);

            environ.put("UnLiKeLYeNVIROmtNam", "someVal");
            checkSizes(environ, size+1);

            // Check for environment independence
            new ProcessBuilder().environment().clear();

            environ.put("UnLiKeLYeNVIROmtNam", "someOtherVal");
            checkSizes(environ, size+1);

            environ.remove("UnLiKeLYeNVIROmtNam");
            checkSizes(environ, size);

            environ.clear();
            checkSizes(environ, 0);

            environ.clear();
            checkSizes(environ, 0);

            environ = new ProcessBuilder().environment();
            environ.keySet().clear();
            checkSizes(environ, 0);

            environ = new ProcessBuilder().environment();
            environ.entrySet().clear();
            checkSizes(environ, 0);

            environ = new ProcessBuilder().environment();
            environ.values().clear();
            checkSizes(environ, 0);
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Check that various map invariants hold
        //----------------------------------------------------------------
        checkMapSanity(new ProcessBuilder().environment());
        checkMapSanity(System.getenv());
        checkMapEquality(new ProcessBuilder().environment(),
                         new ProcessBuilder().environment());


        //----------------------------------------------------------------
        // Check effects on external "env" command.
        //----------------------------------------------------------------
        try {
            Set<String> env1 = new HashSet<String>
                (Arrays.asList(nativeEnv((String[])null).split("\n")));

            ProcessBuilder pb = new ProcessBuilder();
            pb.environment().put("QwErTyUiOp","AsDfGhJk");

            Set<String> env2 = new HashSet<String>
                (Arrays.asList(nativeEnv(pb).split("\n")));

            check(env2.size() == env1.size() + 1);
            env1.add("QwErTyUiOp=AsDfGhJk");
            check(env1.equals(env2));
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Test Runtime.exec(...envp...)
        // Check for sort order of environment variables on Windows.
        //----------------------------------------------------------------
        try {
            String systemRoot = "SystemRoot=" + System.getenv("SystemRoot");
            // '+' < 'A' < 'Z' < '_' < 'a' < 'z' < '~'
            String[]envp = {"FOO=BAR","BAZ=GORP","QUUX=",
                            "+=+", "_=_", "~=~", systemRoot};
            String output = nativeEnv(envp);
            String expected = "+=+\nBAZ=GORP\nFOO=BAR\nQUUX=\n"+systemRoot+"\n_=_\n~=~\n";
            // On Windows, Java must keep the environment sorted.
            // Order is random on Unix, so this test does the sort.
            if (! Windows.is())
                output = sortByLinesWindowsly(output);
            equal(output, expected);
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Test Runtime.exec(...envp...)
        // and check SystemRoot gets set automatically on Windows
        //----------------------------------------------------------------
        try {
            if (Windows.is()) {
                String systemRoot = "SystemRoot=" + System.getenv("SystemRoot");
                String[]envp = {"FOO=BAR","BAZ=GORP","QUUX=",
                                "+=+", "_=_", "~=~"};
                String output = nativeEnv(envp);
                String expected = "+=+\nBAZ=GORP\nFOO=BAR\nQUUX=\n"+systemRoot+"\n_=_\n~=~\n";
                equal(output, expected);
            }
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // System.getenv() must be consistent with System.getenv(String)
        //----------------------------------------------------------------
        try {
            for (Map.Entry<String,String> e : getenv().entrySet())
                equal(getenv(e.getKey()), e.getValue());
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Fiddle with working directory in child
        //----------------------------------------------------------------
        try {
            String canonicalUserDir =
                new File(System.getProperty("user.dir")).getCanonicalPath();
            String[] sdirs = new String[]
                {".", "..", "/", "/bin",
                 "C:", "c:", "C:/", "c:\\", "\\", "\\bin",
                 "c:\\windows  ", "c:\\Program Files", "c:\\Program Files\\" };
            for (String sdir : sdirs) {
                File dir = new File(sdir);
                if (! (dir.isDirectory() && dir.exists()))
                    continue;
                out.println("Testing directory " + dir);
                //dir = new File(dir.getCanonicalPath());

                ProcessBuilder pb = new ProcessBuilder();
                equal(pb.directory(), null);
                equal(pwdInChild(pb), canonicalUserDir);

                pb.directory(dir);
                equal(pb.directory(), dir);
                equal(pwdInChild(pb), dir.getCanonicalPath());

                pb.directory(null);
                equal(pb.directory(), null);
                equal(pwdInChild(pb), canonicalUserDir);

                pb.directory(dir);
            }
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Working directory with Unicode in child
        //----------------------------------------------------------------
        try {
            if (UnicodeOS.is()) {
                File dir = new File(System.getProperty("test.dir", "."),
                                    "ProcessBuilderDir\u4e00\u4e02");
                try {
                    if (!dir.exists())
                        dir.mkdir();
                    out.println("Testing Unicode directory:" + dir);
                    ProcessBuilder pb = new ProcessBuilder();
                    pb.directory(dir);
                    equal(pwdInChild(pb), dir.getCanonicalPath());
                } finally {
                    if (dir.exists())
                        dir.delete();
                }
            }
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // OOME in child allocating maximally sized array
        // Test for hotspot/jvmti bug 6850957
        //----------------------------------------------------------------
        try {
            List<String> list = new ArrayList<String>(javaChildArgs);
            list.add(1, String.format("-XX:OnOutOfMemoryError=%s -version",
                                      javaExe));
            list.add("ArrayOOME");
            ProcessResults r = run(new ProcessBuilder(list));
            check(r.err().contains("java.lang.OutOfMemoryError:"));
            check(r.err().contains(javaExe));
            check(r.err().contains(System.getProperty("java.version")));
            equal(r.exitValue(), 1);
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Windows has tricky semi-case-insensitive semantics
        //----------------------------------------------------------------
        if (Windows.is())
            try {
                out.println("Running case insensitve variable tests");
                for (String[] namePair :
                         new String[][]
                    { new String[]{"PATH","PaTh"},
                      new String[]{"home","HOME"},
                      new String[]{"SYSTEMROOT","SystemRoot"}}) {
                    check((getenv(namePair[0]) == null &&
                           getenv(namePair[1]) == null)
                          ||
                          getenv(namePair[0]).equals(getenv(namePair[1])),
                          "Windows environment variables are not case insensitive");
                }
            } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Test proper Unicode child environment transfer
        //----------------------------------------------------------------
        if (UnicodeOS.is())
            try {
                ProcessBuilder pb = new ProcessBuilder();
                pb.environment().put("\u1234","\u5678");
                pb.environment().remove("PATH");
                equal(getenvInChild1234(pb), "\u5678");
            } catch (Throwable t) { unexpected(t); }


        //----------------------------------------------------------------
        // Test Runtime.exec(...envp...) with envstrings with initial `='
        //----------------------------------------------------------------
        try {
            List<String> childArgs = new ArrayList<String>(javaChildArgs);
            childArgs.add("System.getenv()");
            String[] cmdp = childArgs.toArray(new String[childArgs.size()]);
            String[] envp;
            String[] envpWin = {"=C:=\\", "=ExitValue=3", "SystemRoot="+systemRoot};
            String[] envpOth = {"=ExitValue=3", "=C:=\\"};
            if (Windows.is()) {
                envp = envpWin;
            } else if (AIX.is()) {
                envp = new String[] {"=ExitValue=3", "=C:=\\", "LIBPATH=" + libpath};
            } else {
                envp = envpOth;
            }
            Process p = Runtime.getRuntime().exec(cmdp, envp);
            String expected = Windows.is() ? "=C:=\\,=ExitValue=3,SystemRoot="+systemRoot+"," : "=C:=\\,";
            expected = AIX.is() ? expected + "LIBPATH="+libpath+",": expected;
            String commandOutput = commandOutput(p);
            if (MacOSX.is()) {
                commandOutput = removeMacExpectedVars(commandOutput);
            }
            if (AIX.is()) {
                commandOutput = removeAixExpectedVars(commandOutput);
            }
            equal(commandOutput, expected);
            if (Windows.is()) {
                ProcessBuilder pb = new ProcessBuilder(childArgs);
                pb.environment().clear();
                pb.environment().put("SystemRoot", systemRoot);
                pb.environment().put("=ExitValue", "3");
                pb.environment().put("=C:", "\\");
                equal(commandOutput(pb), expected);
            }
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Test Runtime.exec(...envp...) with envstrings without any `='
        //----------------------------------------------------------------
        try {
            // In Windows CMD (`cmd.exe`), `echo/` outputs a newline (i.e., an empty line).
            // Wrapping it with `cmd.exe /c` ensures compatibility in both native Windows and Cygwin environments.
            String[] cmdp = Windows.is() ? new String[]{"cmd.exe", "/c", "echo/"} : new String[]{"echo"};
            String[] envp = {"Hello", "World"}; // Yuck!
            Process p = Runtime.getRuntime().exec(cmdp, envp);
            equal(commandOutput(p), "\n");
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Test Runtime.exec(...envp...) with envstrings containing NULs
        //----------------------------------------------------------------
        try {
            List<String> childArgs = new ArrayList<String>(javaChildArgs);
            childArgs.add("System.getenv()");
            String[] cmdp = childArgs.toArray(new String[childArgs.size()]);
            String[] envpWin = {"SystemRoot="+systemRoot, "LC_ALL=C\u0000\u0000", // Yuck!
                             "FO\u0000=B\u0000R"};
            String[] envpOth = {"LC_ALL=C\u0000\u0000", // Yuck!
                             "FO\u0000=B\u0000R"};
            String[] envp;
            if (Windows.is()) {
                envp = envpWin;
            } else if (AIX.is()) {
                envp = new String[] {"LC_ALL=C\u0000\u0000", // Yuck!
                        "FO\u0000=B\u0000R", "LIBPATH=" + libpath};
            } else {
                envp = envpOth;
            }
            System.out.println ("cmdp");
            for (int i=0; i<cmdp.length; i++) {
                System.out.printf ("cmdp %d: %s\n", i, cmdp[i]);
            }
            System.out.println ("envp");
            for (int i=0; i<envp.length; i++) {
                System.out.printf ("envp %d: %s\n", i, envp[i]);
            }
            Process p = Runtime.getRuntime().exec(cmdp, envp);
            String commandOutput = commandOutput(p);
            if (MacOSX.is()) {
                commandOutput = removeMacExpectedVars(commandOutput);
            }
            if (AIX.is()) {
                commandOutput = removeAixExpectedVars(commandOutput);
            }
            check(commandOutput.equals(Windows.is()
                    ? "LC_ALL=C,SystemRoot="+systemRoot+","
                    : AIX.is()
                            ? "LC_ALL=C,LIBPATH="+libpath+","
                            : "LC_ALL=C,"),
                  "Incorrect handling of envstrings containing NULs");
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Test the redirectErrorStream property
        //----------------------------------------------------------------
        try {
            ProcessBuilder pb = new ProcessBuilder();
            equal(pb.redirectErrorStream(), false);
            equal(pb.redirectErrorStream(true), pb);
            equal(pb.redirectErrorStream(), true);
            equal(pb.redirectErrorStream(false), pb);
            equal(pb.redirectErrorStream(), false);
        } catch (Throwable t) { unexpected(t); }

        try {
            List<String> childArgs = new ArrayList<String>(javaChildArgs);
            childArgs.add("OutErr");
            ProcessBuilder pb = new ProcessBuilder(childArgs);
            {
                ProcessResults r = run(pb);
                equal(r.out(), "outout");
                equal(r.err(), "errerr");
            }
            {
                pb.redirectErrorStream(true);
                ProcessResults r = run(pb);
                equal(r.out(), "outerrouterr");
                equal(r.err(), "");
            }
        } catch (Throwable t) { unexpected(t); }

        if (Unix.is()) {
            //----------------------------------------------------------------
            // We can find true and false when PATH is null
            //----------------------------------------------------------------
            try {
                List<String> childArgs = new ArrayList<String>(javaChildArgs);
                childArgs.add("null PATH");
                ProcessBuilder pb = new ProcessBuilder(childArgs);
                pb.environment().remove("PATH");
                ProcessResults r = run(pb);
                equal(r.out(), "");
                equal(r.err(), "");
                equal(r.exitValue(), 0);
            } catch (Throwable t) { unexpected(t); }

            //----------------------------------------------------------------
            // PATH search algorithm on Unix
            //----------------------------------------------------------------
            try {
                List<String> childArgs = new ArrayList<String>(javaChildArgs);
                childArgs.add("PATH search algorithm");
                ProcessBuilder pb = new ProcessBuilder(childArgs);
                pb.environment().put("PATH", "dir1:dir2:");
                ProcessResults r = run(pb);
                equal(r.out(), "");
                equal(r.err(), "");
                equal(r.exitValue(), True.exitValue());
            } catch (Throwable t) { unexpected(t); }

            //----------------------------------------------------------------
            // Parent's, not child's PATH is used
            //----------------------------------------------------------------
            try {
                new File("suBdiR").mkdirs();
                copy(TrueExe.path(), "suBdiR/unliKely");
                final ProcessBuilder pb =
                    new ProcessBuilder(new String[]{"unliKely"});
                pb.environment().put("PATH", "suBdiR");
                THROWS(IOException.class, () -> pb.start());
            } catch (Throwable t) { unexpected(t);
            } finally {
                new File("suBdiR/unliKely").delete();
                new File("suBdiR").delete();
            }
        }

        //----------------------------------------------------------------
        // Attempt to start bogus program ""
        //----------------------------------------------------------------
        try {
            new ProcessBuilder("").start();
            fail("Expected IOException not thrown");
        } catch (IOException e) {
            String m = e.getMessage();
            if (EnglishUnix.is() &&
                ! matches(m, NO_SUCH_FILE_ERROR_MSG))
                unexpected(e);
            if (matches(m, SPAWNHELPER_FAILURE_MSG))
                unexpected(e);
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Check that attempt to execute program name with funny
        // characters throws an exception containing those characters.
        //----------------------------------------------------------------
        for (String programName : new String[] {"\u00f0", "\u01f0"})
            try {
                new ProcessBuilder(programName).start();
                fail("Expected IOException not thrown");
            } catch (IOException e) {
                String m = e.getMessage();
                Pattern p = Pattern.compile(programName);
                if (! matches(m, programName)
                    || (EnglishUnix.is() &&
                        ! matches(m, NO_SUCH_FILE_ERROR_MSG)))
                    unexpected(e);
                if (matches(m, SPAWNHELPER_FAILURE_MSG))
                    unexpected(e);
            } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Attempt to start process in nonexistent directory fails.
        //----------------------------------------------------------------
        try {
            new ProcessBuilder("echo")
                .directory(new File("UnLiKeLY"))
                .start();
            fail("Expected IOException not thrown");
        } catch (IOException e) {
            String m = e.getMessage();
            if (! matches(m, "in directory")
                || (EnglishUnix.is() &&
                    ! matches(m, NO_SUCH_FILE_ERROR_MSG)))
                unexpected(e);
            if (matches(m, SPAWNHELPER_FAILURE_MSG))
                unexpected(e);
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Attempt to write 4095 bytes to the pipe buffer without a
        // reader to drain it would deadlock, if not for the fact that
        // interprocess pipe buffers are at least 4096 bytes.
        //
        // Also, check that available reports all the bytes expected
        // in the pipe buffer, and that I/O operations do the expected
        // things.
        //----------------------------------------------------------------
        try {
            List<String> childArgs = new ArrayList<String>(javaChildArgs);
            childArgs.add("print4095");
            final int SIZE = 4095;
            final Process p = new ProcessBuilder(childArgs).start();
            print4095(p.getOutputStream(), (byte) '!'); // Might hang!
            p.waitFor();                                // Might hang!
            equal(SIZE, p.getInputStream().available());
            equal(SIZE, p.getErrorStream().available());
            THROWS(IOException.class,
                   () -> { p.getOutputStream().write((byte) '!');
                           p.getOutputStream().flush();});

            final byte[] bytes = new byte[SIZE + 1];
            equal(SIZE, p.getInputStream().read(bytes));
            for (int i = 0; i < SIZE; i++)
                equal((byte) '!', bytes[i]);
            equal((byte) 0, bytes[SIZE]);

            equal(SIZE, p.getErrorStream().read(bytes));
            for (int i = 0; i < SIZE; i++)
                equal((byte) 'E', bytes[i]);
            equal((byte) 0, bytes[SIZE]);

            equal(0, p.getInputStream().available());
            equal(0, p.getErrorStream().available());
            equal(-1, p.getErrorStream().read());
            equal(-1, p.getInputStream().read());

            equal(p.exitValue(), 5);

            p.getInputStream().close();
            p.getErrorStream().close();
            try { p.getOutputStream().close(); } catch (IOException flushFailed) { }

            InputStream[] streams = { p.getInputStream(), p.getErrorStream() };
            for (final InputStream in : streams) {
                Fun[] ops = {
                    () -> in.read(),
                    () -> in.read(bytes),
                    () -> in.available()
                };
                for (Fun op : ops) {
                    try {
                        op.f();
                        fail();
                    } catch (IOException expected) {
                        String m = expected.getMessage();
                        check(m.matches("[Ss]tream [Cc]losed"));
                        check(!matches(m, SPAWNHELPER_FAILURE_MSG));
                    }
                }
            }
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Check that reads which are pending when Process.destroy is
        // called, get EOF, or IOException("Stream closed").
        //----------------------------------------------------------------
        try {
            final int cases = 4;
            for (int i = 0; i < cases; i++) {
                final int action = i;
                List<String> childArgs = getSleepArgs();
                final ProcessBuilder pb = new ProcessBuilder(childArgs);
                final byte[] bytes = new byte[10];
                final Process p = pb.start();
                final CountDownLatch latch = new CountDownLatch(1);
                final InputStream s;
                switch (action & 0x1) {
                    case 0: s = p.getInputStream(); break;
                    case 1: s = p.getErrorStream(); break;
                    default: throw new Error();
                }
                final Thread thread = new Thread() {
                    public void run() {
                        try {
                            int r;
                            latch.countDown();
                            switch (action & 0x2) {
                                case 0: r = s.read(); break;
                                case 2: r = s.read(bytes); break;
                                default: throw new Error();
                            }
                            if (r >= 0) {
                                // The child sent unexpected output; print it to diagnose
                                System.out.println("Unexpected child output, to: " +
                                        ((action & 0x1) == 0 ? "getInputStream" : "getErrorStream"));
                                System.out.println("Child args: " + childArgs);
                                if ((action & 0x2) == 0) {
                                    System.out.write(r);    // Single character

                                } else {
                                    System.out.write(bytes, 0, r);
                                }
                                for (int c = s.read(); c >= 0; c = s.read())
                                    System.out.write(c);
                                System.out.println("\nEND Child output.");
                            }
                            equal(-1, r);
                        } catch (IOException ioe) {
                            String m = ioe.getMessage();
                            if (!m.equals("Stream closed")) {
                                // BufferedInputStream may throw IOE("Stream closed").
                                unexpected(ioe);
                            }
                            if (matches(m, SPAWNHELPER_FAILURE_MSG)) {
                                unexpected(ioe);
                            }
                        } catch (Throwable t) { unexpected(t); }}};

                thread.start();
                latch.await();
                Thread.sleep(30);

                if (s instanceof BufferedInputStream) {
                    // Wait until after the s.read occurs in "thread" by
                    // checking when the input stream monitor is acquired
                    // (BufferedInputStream.read is synchronized)
                    while (!isLocked((BufferedInputStream) s)) {
                        Thread.sleep(100);
                    }
                }
                p.destroy();
                thread.join();
            }
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Check that subprocesses which create subprocesses of their
        // own do not cause parent to hang waiting for file
        // descriptors to be closed.
        //----------------------------------------------------------------
        try {
            if (Unix.is()
                && new File("/bin/bash").exists()
                && new File("/bin/sleep").exists()) {
                // Notice that we only destroy the process created by us (i.e.
                // our child) but not our grandchild (i.e. '/bin/sleep'). So
                // pay attention that the grandchild doesn't run too long to
                // avoid polluting the process space with useless processes.
                // Running the grandchild for 59s should be more than enough.
                // A unique (59s) time is needed to avoid killing other sleep processes.
                final String[] cmd = { "/bin/bash", "-c", "(/bin/sleep 59)" };
                final String[] cmdkill = { "/bin/bash", "-c", "(/usr/bin/pkill -f \"sleep 59\")" };
                final ProcessBuilder pb = new ProcessBuilder(cmd);
                final Process p = pb.start();
                final InputStream stdout = p.getInputStream();
                final InputStream stderr = p.getErrorStream();
                final OutputStream stdin = p.getOutputStream();
                final Thread reader = new Thread() {
                    public void run() {
                        try { stdout.read(); }
                        catch (IOException e) {
                            // Check that reader failed because stream was
                            // asynchronously closed.
                            // e.printStackTrace();
                            String msg = e.getMessage();
                            if (EnglishUnix.is() &&
                                ! (msg.matches(".*Bad file.*") ||
                                        msg.matches(".*Stream closed.*")))
                                unexpected(e);
                            if (matches(msg, SPAWNHELPER_FAILURE_MSG)) {
                                unexpected(e);
                            }
                        }
                        catch (Throwable t) { unexpected(t); }}};
                reader.setDaemon(true);
                reader.start();
                Thread.sleep(100);
                p.destroy();
                check(p.waitFor() != 0);
                check(p.exitValue() != 0);
                // Subprocess is now dead, but file descriptors remain open.
                // Make sure the test will fail if we don't manage to close
                // the open streams within 30 seconds. Notice that this time
                // must be shorter than the sleep time of the grandchild.
                Timer t = new Timer("test/java/lang/ProcessBuilder/Basic.java process reaper", true);
                t.schedule(new TimerTask() {
                      public void run() {
                          fail("Subprocesses which create subprocesses of " +
                               "their own caused the parent to hang while " +
                               "waiting for file descriptors to be closed.");
                          System.exit(-1);
                      }
                  }, 30000);
                stdout.close();
                stderr.close();
                stdin.close();
                new ProcessBuilder(cmdkill).start();
                // All streams successfully closed so we can cancel the timer.
                t.cancel();
                //----------------------------------------------------------
                // There remain unsolved issues with asynchronous close.
                // Here's a highly non-portable experiment to demonstrate:
                //----------------------------------------------------------
                if (Boolean.getBoolean("wakeupJeff!")) {
                    System.out.println("wakeupJeff!");
                    // Initialize signal handler for INTERRUPT_SIGNAL.
                    new FileInputStream("/bin/sleep").getChannel().close();
                    // Send INTERRUPT_SIGNAL to every thread in this java.
                    String[] wakeupJeff = {
                        "/bin/bash", "-c",
                        "/bin/ps --noheaders -Lfp $PPID | " +
                        "/usr/bin/perl -nale 'print $F[3]' | " +
                        // INTERRUPT_SIGNAL == 62 on my machine du jour.
                        "/usr/bin/xargs kill -62"
                    };
                    new ProcessBuilder(wakeupJeff).start().waitFor();
                    // If wakeupJeff worked, reader probably got EBADF.
                    reader.join();
                }
            }

            //----------------------------------------------------------------
            // Check the Process toString() method
            //----------------------------------------------------------------
            {
                List<String> childArgs = new ArrayList<String>(javaChildArgs);
                childArgs.add("testIO");
                ProcessBuilder pb = new ProcessBuilder(childArgs);
                pb.redirectInput(Redirect.PIPE);
                pb.redirectOutput(DISCARD);
                pb.redirectError(DISCARD);
                final Process p = pb.start();
                // Child process waits until it gets input
                String s = p.toString();
                check(s.contains("not exited"));
                check(s.contains("pid=" + p.pid() + ","));

                new PrintStream(p.getOutputStream()).print("standard input");
                p.getOutputStream().close();

                // Check the toString after it exits
                int exitValue = p.waitFor();
                s = p.toString();
                check(s.contains("pid=" + p.pid() + ","));
                check(s.contains("exitValue=" + exitValue) &&
                        !s.contains("not exited"));
            }
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Attempt to start process with insufficient permissions fails.
        //----------------------------------------------------------------
        try {
            new File("emptyCommand").delete();
            new FileOutputStream("emptyCommand").close();
            new File("emptyCommand").setExecutable(false);
            new ProcessBuilder("./emptyCommand").start();
            fail("Expected IOException not thrown");
        } catch (IOException e) {
            new File("./emptyCommand").delete();
            String m = e.getMessage();
            if (EnglishUnix.is() &&
                ! matches(m, PERMISSION_DENIED_ERROR_MSG))
                unexpected(e);
            if (matches(m, SPAWNHELPER_FAILURE_MSG)) {
                unexpected(e);
            }
        } catch (Throwable t) { unexpected(t); }

        new File("emptyCommand").delete();

        //----------------------------------------------------------------
        // Check that Process.isAlive() &
        // Process.waitFor(0, TimeUnit.MILLISECONDS) work as expected.
        //----------------------------------------------------------------
        try {
            List<String> childArgs = getSleepArgs();
            final Process p = new ProcessBuilder(childArgs).start();
            long start = System.nanoTime();
            if (!p.isAlive() || p.waitFor(0, TimeUnit.MILLISECONDS)) {
                fail("Test failed: Process exited prematurely");
            }
            long end = System.nanoTime();
            // give waitFor(timeout) a wide berth (2s)
            System.out.printf(" waitFor process: delta: %d%n",(end - start) );

            if ((end - start) > TimeUnit.SECONDS.toNanos(2))
                fail("Test failed: waitFor took too long (" + (end - start) + "ns)");

            p.destroy();
            p.waitFor();

            if (p.isAlive() ||
                !p.waitFor(0, TimeUnit.MILLISECONDS))
            {
                fail("Test failed: Process still alive - please terminate " +
                    p.toString() + " manually");
            }
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Check that Process.waitFor(timeout, TimeUnit.MILLISECONDS)
        // works as expected.
        //----------------------------------------------------------------
        try {
            List<String> childArgs = getSleepArgs();
            final Process p = new ProcessBuilder(childArgs).start();
            long start = System.nanoTime();

            if (p.waitFor(10, TimeUnit.MILLISECONDS)) {
                var msg = "External sleep process terminated early: exitValue: %d, (%dns)%n"
                        .formatted(p.exitValue(), (System.nanoTime() - start));
                fail(msg);
            } else {
                long end = System.nanoTime();
                if ((end - start) < TimeUnit.MILLISECONDS.toNanos(10))
                    fail("Test failed: waitFor didn't take long enough (" + (end - start) + "ns)");
            }
            p.destroy();
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Check that Process.waitFor(timeout, TimeUnit.MILLISECONDS)
        // interrupt works as expected, if interrupted while waiting.
        //----------------------------------------------------------------
        try {
            List<String> childArgs = getSleepArgs();
            final Process p = new ProcessBuilder(childArgs).start();
            final long start = System.nanoTime();
            final CountDownLatch aboutToWaitFor = new CountDownLatch(1);

            final Thread thread = new Thread() {
                public void run() {
                    try {
                        aboutToWaitFor.countDown();
                        Thread.currentThread().interrupt();
                        boolean result = p.waitFor(30L * 1000L, TimeUnit.MILLISECONDS);
                        fail("waitFor() wasn't interrupted, its return value was: " + result);
                    } catch (InterruptedException success) {
                    } catch (Throwable t) { unexpected(t); }
                }
            };

            thread.start();
            aboutToWaitFor.await();
            thread.interrupt();
            thread.join(10L * 1000L);
            check(millisElapsedSince(start) < 10L * 1000L);
            check(!thread.isAlive());
            p.destroy();
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Check that Process.waitFor(Long.MAX_VALUE, TimeUnit.MILLISECONDS)
        // interrupt works as expected, if interrupted while waiting.
        //----------------------------------------------------------------
        try {
            List<String> childArgs = getSleepArgs();
            final Process p = new ProcessBuilder(childArgs).start();
            final long start = System.nanoTime();
            final CountDownLatch aboutToWaitFor = new CountDownLatch(1);

            final Thread thread = new Thread() {
                public void run() {
                    try {
                        aboutToWaitFor.countDown();
                        Thread.currentThread().interrupt();
                        boolean result = p.waitFor(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
                        fail("waitFor() wasn't interrupted, its return value was: " + result);
                    } catch (InterruptedException success) {
                    } catch (Throwable t) { unexpected(t); }
                }
            };

            thread.start();
            aboutToWaitFor.await();
            thread.interrupt();
            thread.join(10L * 1000L);
            check(millisElapsedSince(start) < 10L * 1000L);
            check(!thread.isAlive());
            p.destroy();
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Check that Process.waitFor(timeout, TimeUnit.MILLISECONDS)
        // interrupt works as expected, if interrupted before waiting.
        //----------------------------------------------------------------
        try {
            List<String> childArgs = getSleepArgs();
            final Process p = new ProcessBuilder(childArgs).start();
            final long start = System.nanoTime();
            final CountDownLatch threadStarted = new CountDownLatch(1);

            final Thread thread = new Thread() {
                public void run() {
                    try {
                        threadStarted.countDown();
                        do { Thread.yield(); }
                        while (!Thread.currentThread().isInterrupted());
                        boolean result = p.waitFor(30L * 1000L, TimeUnit.MILLISECONDS);
                        fail("waitFor() wasn't interrupted, its return value was: " + result);
                    } catch (InterruptedException success) {
                    } catch (Throwable t) { unexpected(t); }
                }
            };

            thread.start();
            threadStarted.await();
            thread.interrupt();
            thread.join(10L * 1000L);
            check(millisElapsedSince(start) < 10L * 1000L);
            check(!thread.isAlive());
            p.destroy();
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Check that Process.waitFor(timeout, null) throws NPE.
        //----------------------------------------------------------------
        try {
            List<String> childArgs = getSleepArgs();
            final Process p = new ProcessBuilder(childArgs).start();
            THROWS(NullPointerException.class,
                    () ->  p.waitFor(10L, null));
            THROWS(NullPointerException.class,
                    () ->  p.waitFor(0L, null));
            THROWS(NullPointerException.class,
                    () -> p.waitFor(-1L, null));
            // Terminate process and recheck after it exits
            p.destroy();
            p.waitFor();
            THROWS(NullPointerException.class,
                    () -> p.waitFor(10L, null));
            THROWS(NullPointerException.class,
                    () -> p.waitFor(0L, null));
            THROWS(NullPointerException.class,
                    () -> p.waitFor(-1L, null));
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Check that default implementation of Process.waitFor(timeout, null) throws NPE.
        //----------------------------------------------------------------
        try {
            List<String> childArgs = getSleepArgs();
            final Process proc = new ProcessBuilder(childArgs).start();
            final DelegatingProcess p = new DelegatingProcess(proc);

            THROWS(NullPointerException.class,
                    () ->  p.waitFor(10L, null));
            THROWS(NullPointerException.class,
                    () ->  p.waitFor(0L, null));
            THROWS(NullPointerException.class,
                    () ->  p.waitFor(-1L, null));
            // Terminate process and recheck after it exits
            p.destroy();
            p.waitFor();
            THROWS(NullPointerException.class,
                    () -> p.waitFor(10L, null));
            THROWS(NullPointerException.class,
                    () -> p.waitFor(0L, null));
            THROWS(NullPointerException.class,
                    () -> p.waitFor(-1L, null));
        } catch (Throwable t) { unexpected(t); }

        //----------------------------------------------------------------
        // Check the default implementation for
        // Process.waitFor(long, TimeUnit)
        //----------------------------------------------------------------
        try {
            List<String> childArgs = getSleepArgs();
            final Process proc = new ProcessBuilder(childArgs).start();
            DelegatingProcess p = new DelegatingProcess(proc);
            long start = System.nanoTime();

            if (p.waitFor(1000, TimeUnit.MILLISECONDS)) {
                var msg = "External sleep process terminated early: exitValue: %02x, (%dns)"
                        .formatted(p.exitValue(), (System.nanoTime() - start));
                fail(msg);
            } else {
                long end = System.nanoTime();
                if ((end - start) < 500000000)
                    fail("Test failed: waitFor didn't take long enough (" + (end - start) + "ns)");
            }
            p.destroy();

            p.waitFor(1000, TimeUnit.MILLISECONDS);
        } catch (Throwable t) { unexpected(t); }
    }

    // Path to native executables, if any
    private static final String TEST_NATIVEPATH = System.getProperty("test.nativepath");

    // Path where "sleep" program may be found" or null
    private static final Path SLEEP_PATH = initSleepPath();

    /**
     * Compute the Path to a sleep executable.
     * @return a Path to sleep or BasicSleep(.exe) or null if none
     */
    private static Path initSleepPath() {
        if (Windows.is() && TEST_NATIVEPATH != null) {
            // exeBasicSleep is equivalent to sleep on Unix
            Path exePath = Path.of(TEST_NATIVEPATH).resolve("BasicSleep.exe");
            if (Files.isExecutable(exePath)) {
                return exePath;
            }
        }

        List<String> binPaths = List.of("/bin", "/usr/bin");
        for (String dir : binPaths) {
            Path exePath = Path.of(dir).resolve("sleep");
            if (Files.isExecutable(exePath)) {
                return exePath;
            }
        }
        return null;
    }

    /**
     * Return the list of process arguments for a child to sleep 10 minutes (600 seconds).
     *
     * @return A list of process arguments to sleep 10 minutes.
     */
    private static List<String> getSleepArgs() {
        List<String> childArgs = null;
        if (SLEEP_PATH != null) {
            childArgs = List.of(SLEEP_PATH.toString(), "600");
        } else {
            // Fallback to the JavaChild ; its 'sleep' command is for 10 minutes.
            // The fallback the Java$Child is used if the test is run without building
            // the BasicSleep native executable (for Windows).
            childArgs = new ArrayList<>(javaChildArgs);
            childArgs.add("sleep");
            System.out.println("Sleep not found, fallback to JavaChild: " + childArgs);
        }
        return childArgs;
    }

    static void closeStreams(Process p) {
        try {
            p.getOutputStream().close();
            p.getInputStream().close();
            p.getErrorStream().close();
        } catch (Throwable t) { unexpected(t); }
    }

    private static class StreamAccumulator extends Thread {
        private final InputStream is;
        private final StringBuilder sb = new StringBuilder();
        private Throwable throwable = null;

        public String result () throws Throwable {
            if (throwable != null)
                throw throwable;
            return sb.toString();
        }

        StreamAccumulator (InputStream is) {
            this.is = is;
        }

        public void run() {
            try {
                Reader r = new InputStreamReader(is);
                char[] buf = new char[4096];
                int n;
                while ((n = r.read(buf)) > 0) {
                    sb.append(buf,0,n);
                }
            } catch (Throwable t) {
                throwable = t;
            } finally {
                try { is.close(); }
                catch (Throwable t) { throwable = t; }
            }
        }
    }

    static ProcessResults run(ProcessBuilder pb) {
        try {
            return run(pb.start());
        } catch (Throwable t) { unexpected(t); return null; }
    }

    private static ProcessResults run(Process p) {
        Throwable throwable = null;
        int exitValue = -1;
        String out = "";
        String err = "";

        StreamAccumulator outAccumulator =
            new StreamAccumulator(p.getInputStream());
        StreamAccumulator errAccumulator =
            new StreamAccumulator(p.getErrorStream());

        try {
            outAccumulator.start();
            errAccumulator.start();

            exitValue = p.waitFor();

            outAccumulator.join();
            errAccumulator.join();

            out = outAccumulator.result();
            err = errAccumulator.result();
        } catch (Throwable t) {
            throwable = t;
        }

        return new ProcessResults(out, err, exitValue, throwable);
    }

    //----------------------------------------------------------------
    // Results of a command
    //----------------------------------------------------------------
    private static class ProcessResults {
        private final String out;
        private final String err;
        private final int exitValue;
        private final Throwable throwable;

        public ProcessResults(String out,
                              String err,
                              int exitValue,
                              Throwable throwable) {
            this.out = out;
            this.err = err;
            this.exitValue = exitValue;
            this.throwable = throwable;
        }

        public String out()          { return out; }
        public String err()          { return err; }
        public int exitValue()       { return exitValue; }
        public Throwable throwable() { return throwable; }

        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("<STDOUT>\n" + out() + "</STDOUT>\n")
                .append("<STDERR>\n" + err() + "</STDERR>\n")
                .append("exitValue = " + exitValue + "\n");
            if (throwable != null)
                sb.append(throwable.getStackTrace());
            return sb.toString();
        }
    }

    //--------------------- Infrastructure ---------------------------
    static volatile int passed = 0, failed = 0;
    static void pass() {passed++;}
    static void fail() {failed++; Thread.dumpStack();}
    static void fail(String msg) {System.err.println(msg); fail();}
    static void unexpected(Throwable t) {failed++; t.printStackTrace();}
    static void check(boolean cond) {if (cond) pass(); else fail();}
    static void check(boolean cond, String m) {if (cond) pass(); else fail(m);}
    static void equal(Object x, Object y) {
        if (x == null ? y == null : x.equals(y)) pass();
        else fail(">'" + x + "'<" + " not equal to " + "'" + y + "'");}

    public static void main(String[] args) throws Throwable {
        try {realMain(args);} catch (Throwable t) {unexpected(t);}
        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
        if (failed > 0) throw new AssertionError("Some tests failed");}
    interface Fun {void f() throws Throwable;}
    static void THROWS(Class<? extends Throwable> k, Fun... fs) {
        for (Fun f : fs)
            try { f.f(); fail("Expected " + k.getName() + " not thrown"); }
            catch (Throwable t) {
                if (k.isAssignableFrom(t.getClass())) pass();
                else unexpected(t);}}

    static boolean isLocked(BufferedInputStream bis) throws Exception {
        return new Thread() {
            volatile boolean unlocked;

            @Override
            public void run() {
                synchronized (bis) { unlocked = true; }
            }

            boolean isLocked() throws InterruptedException {
                start();
                join(10);
                return !unlocked;
            }
        }.isLocked();
    }
}
