jdk/test/java/lang/ProcessBuilder/Basic.java
author duke
Sat, 01 Dec 2007 00:00:00 +0000
changeset 2 90ce3da70b43
child 48 dc5744ca15ea
permissions -rw-r--r--
Initial load
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
 * @test
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
 * @bug 4199068 4738465 4937983 4930681 4926230 4931433 4932663 4986689
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
 *      5026830 5023243 5070673 4052517 4811767 6192449 6397034 6413313
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
 *      6464154 6523983 6206031
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
 * @summary Basic tests for Process and Environment Variable code
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
 * @run main/othervm Basic
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
 * @author Martin Buchholz
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.io.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.util.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.security.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.util.regex.Pattern;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import static java.lang.System.getenv;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import static java.lang.System.out;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import static java.lang.Boolean.TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import static java.util.AbstractMap.SimpleImmutableEntry;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
public class Basic {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
    private static String commandOutput(Reader r) throws Throwable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
        StringBuilder sb = new StringBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
        int c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
        while ((c = r.read()) > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
            if (c != '\r')
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
                sb.append((char) c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
        return sb.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
    private static String commandOutput(Process p) throws Throwable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
        check(p.getInputStream()  == p.getInputStream());
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
        check(p.getOutputStream() == p.getOutputStream());
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
        check(p.getErrorStream()  == p.getErrorStream());
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
        Reader r = new InputStreamReader(p.getInputStream(),"UTF-8");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
        String output = commandOutput(r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
        equal(p.waitFor(), 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
        equal(p.exitValue(), 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
        return output;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    private static String commandOutput(ProcessBuilder pb) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
            return commandOutput(pb.start());
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
        } catch (Throwable t) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
            String commandline = "";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
            for (String arg : pb.command())
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
                commandline += " " + arg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
            System.out.println("Exception trying to run process: " + commandline);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
            unexpected(t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
            return "";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    private static String commandOutput(String...command) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
            return commandOutput(Runtime.getRuntime().exec(command));
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
        } catch (Throwable t) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
            String commandline = "";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
            for (String arg : command)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
                commandline += " " + arg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
            System.out.println("Exception trying to run process: " + commandline);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
            unexpected(t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
            return "";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    private static void checkCommandOutput(ProcessBuilder pb,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
                                           String expected,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
                                           String failureMsg) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
        String got = commandOutput(pb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
        check(got.equals(expected),
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
              failureMsg + "\n" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
              "Expected: \"" + expected + "\"\n" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
              "Got: \"" + got + "\"");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    private static String absolutifyPath(String path) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
        StringBuilder sb = new StringBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
        for (String file : path.split(File.pathSeparator)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
            if (sb.length() != 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
                sb.append(File.pathSeparator);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
            sb.append(new File(file).getAbsolutePath());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
        return sb.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    // compare windows-style, by canonicalizing to upper case,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    // not lower case as String.compareToIgnoreCase does
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    private static class WindowsComparator
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
        implements Comparator<String> {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
        public int compare(String x, String y) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
            return x.toUpperCase(Locale.US)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
                .compareTo(y.toUpperCase(Locale.US));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    private static String sortedLines(String lines) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
        String[] arr = lines.split("\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
        List<String> ls = new ArrayList<String>();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
        for (String s : arr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
            ls.add(s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
        Collections.sort(ls, new WindowsComparator());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
        StringBuilder sb = new StringBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        for (String s : ls)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
            sb.append(s + "\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        return sb.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    private static void compareLinesIgnoreCase(String lines1, String lines2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
        if (! (sortedLines(lines1).equalsIgnoreCase(sortedLines(lines2)))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
            String dashes =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
                "-----------------------------------------------------";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
            out.println(dashes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
            out.print(sortedLines(lines1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
            out.println(dashes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
            out.print(sortedLines(lines2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
            out.println(dashes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
            out.println("sizes: " + sortedLines(lines1).length() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
                        " " + sortedLines(lines2).length());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
            fail("Sorted string contents differ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
    private static final Runtime runtime = Runtime.getRuntime();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    private static final String[] winEnvCommand = {"cmd.exe", "/c", "set"};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    private static String winEnvFilter(String env) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
        return env.replaceAll("\r", "")
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
            .replaceAll("(?m)^(?:COMSPEC|PROMPT|PATHEXT)=.*\n","");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    private static String unixEnvProg() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
        return new File("/usr/bin/env").canExecute() ? "/usr/bin/env"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
            : "/bin/env";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    private static String nativeEnv(String[] env) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
            if (Windows.is()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
                return winEnvFilter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
                    (commandOutput(runtime.exec(winEnvCommand, env)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
                return commandOutput(runtime.exec(unixEnvProg(), env));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        } catch (Throwable t) { throw new Error(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
    private static String nativeEnv(ProcessBuilder pb) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
            if (Windows.is()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
                pb.command(winEnvCommand);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
                return winEnvFilter(commandOutput(pb));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
                pb.command(new String[]{unixEnvProg()});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
                return commandOutput(pb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        } catch (Throwable t) { throw new Error(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
    private static void checkSizes(Map<String,String> environ, int size) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
            equal(size, environ.size());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            equal(size, environ.entrySet().size());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
            equal(size, environ.keySet().size());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
            equal(size, environ.values().size());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
            boolean isEmpty = (size == 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
            equal(isEmpty, environ.isEmpty());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
            equal(isEmpty, environ.entrySet().isEmpty());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
            equal(isEmpty, environ.keySet().isEmpty());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
            equal(isEmpty, environ.values().isEmpty());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    private interface EnvironmentFrobber {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        void doIt(Map<String,String> environ);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
    private static void testVariableDeleter(EnvironmentFrobber fooDeleter) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
            Map<String,String> environ = new ProcessBuilder().environment();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
            environ.put("Foo", "BAAR");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
            fooDeleter.doIt(environ);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
            equal(environ.get("Foo"), null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
            equal(environ.remove("Foo"), null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
    private static void testVariableAdder(EnvironmentFrobber fooAdder) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
            Map<String,String> environ = new ProcessBuilder().environment();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
            environ.remove("Foo");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
            fooAdder.doIt(environ);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
            equal(environ.get("Foo"), "Bahrein");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
    private static void testVariableModifier(EnvironmentFrobber fooModifier) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
            Map<String,String> environ = new ProcessBuilder().environment();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
            environ.put("Foo","OldValue");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
            fooModifier.doIt(environ);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
            equal(environ.get("Foo"), "NewValue");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
    private static void printUTF8(String s) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        out.write(s.getBytes("UTF-8"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
    private static String getenvAsString(Map<String,String> environment) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
        StringBuilder sb = new StringBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
        for (Map.Entry<String,String> e : environment.entrySet())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
            // Ignore magic environment variables added by the launcher
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
            if (! e.getKey().equals("NLSPATH") &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
                ! e.getKey().equals("XFILESEARCHPATH") &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
                ! e.getKey().equals("LD_LIBRARY_PATH"))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
                sb.append(e.getKey())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
                    .append('=')
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
                    .append(e.getValue())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
                    .append(',');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        return sb.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
    static void print4095(OutputStream s) throws Throwable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
        byte[] bytes = new byte[4095];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
        Arrays.fill(bytes, (byte) '!');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        s.write(bytes);         // Might hang!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
    public static class JavaChild {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        public static void main(String args[]) throws Throwable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
            String action = args[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
            if (action.equals("System.getenv(String)")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
                String val = System.getenv(args[1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
                printUTF8(val == null ? "null" : val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
            } else if (action.equals("System.getenv(\\u1234)")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
                String val = System.getenv("\u1234");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
                printUTF8(val == null ? "null" : val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
            } else if (action.equals("System.getenv()")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
                printUTF8(getenvAsString(System.getenv()));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
            } else if (action.equals("pwd")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
                printUTF8(new File(System.getProperty("user.dir"))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
                          .getCanonicalPath());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
            } else if (action.equals("print4095")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
                print4095(System.out);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
                System.exit(5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
            } else if (action.equals("OutErr")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
                // You might think the system streams would be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
                // buffered, and in fact they are implemented using
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
                // BufferedOutputStream, but each and every print
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
                // causes immediate operating system I/O.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
                System.out.print("out");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
                System.err.print("err");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
                System.out.print("out");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
                System.err.print("err");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
            } else if (action.equals("null PATH")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
                equal(System.getenv("PATH"), null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
                check(new File("/bin/true").exists());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
                check(new File("/bin/false").exists());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
                ProcessBuilder pb1 = new ProcessBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
                ProcessBuilder pb2 = new ProcessBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
                pb2.environment().put("PATH", "anyOldPathIgnoredAnyways");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
                ProcessResults r;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
                for (final ProcessBuilder pb :
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
                         new ProcessBuilder[] {pb1, pb2}) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
                    pb.command("true");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
                    r = run(pb.start());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
                    equal(r.exitValue(), True.exitValue());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
                    pb.command("false");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
                    r = run(pb.start());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
                    equal(r.exitValue(), False.exitValue());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                if (failed != 0) throw new Error("null PATH");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
            } else if (action.equals("PATH search algorithm")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
                equal(System.getenv("PATH"), "dir1:dir2:");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
                check(new File("/bin/true").exists());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
                check(new File("/bin/false").exists());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
                String[] cmd = {"prog"};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
                ProcessBuilder pb1 = new ProcessBuilder(cmd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
                ProcessBuilder pb2 = new ProcessBuilder(cmd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
                ProcessBuilder pb3 = new ProcessBuilder(cmd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
                pb2.environment().put("PATH", "anyOldPathIgnoredAnyways");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
                pb3.environment().remove("PATH");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
                for (final ProcessBuilder pb :
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
                         new ProcessBuilder[] {pb1, pb2, pb3}) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
                    try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
                        // Not on PATH at all; directories don't exist
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
                        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
                            pb.start();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
                            fail("Expected IOException not thrown");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
                        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
                            String m = e.getMessage();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
                            if (EnglishUnix.is() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
                                ! matches(m, "No such file"))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
                                unexpected(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
                        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
                        // Not on PATH at all; directories exist
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
                        new File("dir1").mkdirs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                        new File("dir2").mkdirs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
                        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
                            pb.start();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
                            fail("Expected IOException not thrown");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
                        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
                            String m = e.getMessage();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
                            if (EnglishUnix.is() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
                                ! matches(m, "No such file"))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
                                unexpected(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
                        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
                        // Can't execute a directory -- permission denied
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
                        // Report EACCES errno
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
                        new File("dir1/prog").mkdirs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
                        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
                            pb.start();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
                            fail("Expected IOException not thrown");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
                        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
                            String m = e.getMessage();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
                            if (EnglishUnix.is() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
                                ! matches(m, "Permission denied"))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
                                unexpected(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
                        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
                        // continue searching if EACCES
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
                        copy("/bin/true", "dir2/prog");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
                        equal(run(pb.start()).exitValue(), True.exitValue());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
                        new File("dir1/prog").delete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
                        new File("dir2/prog").delete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
                        new File("dir2/prog").mkdirs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
                        copy("/bin/true", "dir1/prog");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
                        equal(run(pb.start()).exitValue(), True.exitValue());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
                        // Check empty PATH component means current directory
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
                        new File("dir1/prog").delete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
                        new File("dir2/prog").delete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
                        copy("/bin/true", "./prog");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
                        equal(run(pb.start()).exitValue(), True.exitValue());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
                        // If prog found on both parent and child's PATH,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
                        // parent's is used.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
                        new File("dir1/prog").delete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
                        new File("dir2/prog").delete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
                        new File("prog").delete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
                        new File("dir3").mkdirs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
                        copy("/bin/true", "dir1/prog");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
                        copy("/bin/false", "dir3/prog");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
                        pb.environment().put("PATH","dir3");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
                        equal(run(pb.start()).exitValue(), True.exitValue());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
                        copy("/bin/true", "dir3/prog");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
                        copy("/bin/false", "dir1/prog");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
                        equal(run(pb.start()).exitValue(), False.exitValue());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
                    } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
                        // cleanup
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
                        new File("dir1/prog").delete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
                        new File("dir2/prog").delete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
                        new File("dir3/prog").delete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
                        new File("dir1").delete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
                        new File("dir2").delete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
                        new File("dir3").delete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
                        new File("prog").delete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
                if (failed != 0) throw new Error("PATH search algorithm");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
            else throw new Error("JavaChild invocation error");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
    private static void copy(String src, String dst) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
        system("/bin/cp", "-fp", src, dst);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
    private static void system(String... command) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
            ProcessBuilder pb = new ProcessBuilder(command);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
            ProcessResults r = run(pb.start());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
            equal(r.exitValue(), 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
            equal(r.out(), "");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
            equal(r.err(), "");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
    private static String javaChildOutput(ProcessBuilder pb, String...args) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
        List<String> list = new ArrayList<String>(javaChildArgs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
        for (String arg : args)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
            list.add(arg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
        pb.command(list);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
        return commandOutput(pb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
    private static String getenvInChild(ProcessBuilder pb) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        return javaChildOutput(pb, "System.getenv()");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    private static String getenvInChild1234(ProcessBuilder pb) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        return javaChildOutput(pb, "System.getenv(\\u1234)");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
    private static String getenvInChild(ProcessBuilder pb, String name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
        return javaChildOutput(pb, "System.getenv(String)", name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
    private static String pwdInChild(ProcessBuilder pb) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
        return javaChildOutput(pb, "pwd");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
    private static final String javaExe =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
        System.getProperty("java.home") +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        File.separator + "bin" + File.separator + "java";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
    private static final String classpath =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
        System.getProperty("java.class.path");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
    private static final List<String> javaChildArgs =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
        Arrays.asList(new String[]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
            { javaExe, "-classpath", absolutifyPath(classpath),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
              "Basic$JavaChild"});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
    private static void testEncoding(String encoding, String tested) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
            // If round trip conversion works, should be able to set env vars
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
            // correctly in child.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
            if (new String(tested.getBytes()).equals(tested)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
                out.println("Testing " + encoding + " environment values");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
                ProcessBuilder pb = new ProcessBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
                pb.environment().put("ASCIINAME",tested);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
                equal(getenvInChild(pb,"ASCIINAME"), tested);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
    static class Windows {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
        public static boolean is() { return is; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
        private static final boolean is =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
            System.getProperty("os.name").startsWith("Windows");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
    static class Unix {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
        public static boolean is() { return is; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
        private static final boolean is =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
            (! Windows.is() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
             new File("/bin/sh").exists() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
             new File("/bin/true").exists() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
             new File("/bin/false").exists());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
    static class UnicodeOS {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
        public static boolean is() { return is; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
        private static final String osName = System.getProperty("os.name");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
        private static final boolean is =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
            // MacOS X would probably also qualify
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
            osName.startsWith("Windows")   &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
            ! osName.startsWith("Windows 9") &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
            ! osName.equals("Windows Me");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
    static class True {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
        public static int exitValue() { return 0; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
    private static class False {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
        public static int exitValue() { return exitValue; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
        private static final int exitValue = exitValue0();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
        private static int exitValue0() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
            // /bin/false returns an *unspecified* non-zero number.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
                if (! Unix.is())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
                    return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
                else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
                    int rc = new ProcessBuilder("/bin/false")
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
                        .start().waitFor();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
                    check(rc != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
                    return rc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
            } catch (Throwable t) { unexpected(t); return -1; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
    static class EnglishUnix {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
        private final static Boolean is =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
            (! Windows.is() && isEnglish("LANG") && isEnglish("LC_ALL"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
        private static boolean isEnglish(String envvar) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
            String val = getenv(envvar);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
            return (val == null) || val.matches("en.*");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
        /** Returns true if we can expect English OS error strings */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
        static boolean is() { return is; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
    private static boolean matches(String str, String regex) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
        return Pattern.compile(regex).matcher(str).find();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
    private static String sortByLinesWindowsly(String text) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        String[] lines = text.split("\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
        Arrays.sort(lines, new WindowsComparator());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
        StringBuilder sb = new StringBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
        for (String line : lines)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
            sb.append(line).append("\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
        return sb.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
    private static void checkMapSanity(Map<String,String> map) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
            Set<String> keySet = map.keySet();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
            Collection<String> values = map.values();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
            Set<Map.Entry<String,String>> entrySet = map.entrySet();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
            equal(entrySet.size(), keySet.size());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
            equal(entrySet.size(), values.size());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
            StringBuilder s1 = new StringBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
            for (Map.Entry<String,String> e : entrySet)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
                s1.append(e.getKey() + "=" + e.getValue() + "\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
            StringBuilder s2 = new StringBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
            for (String var : keySet)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
                s2.append(var + "=" + map.get(var) + "\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
            equal(s1.toString(), s2.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
            Iterator<String> kIter = keySet.iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
            Iterator<String> vIter = values.iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
            Iterator<Map.Entry<String,String>> eIter = entrySet.iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
            while (eIter.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
                Map.Entry<String,String> entry = eIter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
                String key   = kIter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
                String value = vIter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
                check(entrySet.contains(entry));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
                check(keySet.contains(key));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
                check(values.contains(value));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
                check(map.containsKey(key));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
                check(map.containsValue(value));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
                equal(entry.getKey(), key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
                equal(entry.getValue(), value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
            check(! kIter.hasNext() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
                  ! vIter.hasNext());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
    private static void checkMapEquality(Map<String,String> map1,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
                                         Map<String,String> map2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
            equal(map1.size(), map2.size());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
            equal(map1.isEmpty(), map2.isEmpty());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
            for (String key : map1.keySet()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
                equal(map1.get(key), map2.get(key));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
                check(map2.keySet().contains(key));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
            equal(map1, map2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
            equal(map2, map1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
            equal(map1.entrySet(), map2.entrySet());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
            equal(map2.entrySet(), map1.entrySet());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
            equal(map1.keySet(), map2.keySet());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
            equal(map2.keySet(), map1.keySet());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
            equal(map1.hashCode(), map2.hashCode());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
            equal(map1.entrySet().hashCode(), map2.entrySet().hashCode());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
            equal(map1.keySet().hashCode(), map2.keySet().hashCode());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
    private static void realMain(String[] args) throws Throwable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
        if (Windows.is())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
            System.out.println("This appears to be a Windows system.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
        if (Unix.is())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
            System.out.println("This appears to be a Unix system.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
        if (UnicodeOS.is())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
            System.out.println("This appears to be a Unicode-based OS.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
        // Basic tests for setting, replacing and deleting envvars
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
            ProcessBuilder pb = new ProcessBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
            Map<String,String> environ = pb.environment();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
            // New env var
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
            environ.put("QUUX", "BAR");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
            equal(environ.get("QUUX"), "BAR");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
            equal(getenvInChild(pb,"QUUX"), "BAR");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
            // Modify env var
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
            environ.put("QUUX","bear");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
            equal(environ.get("QUUX"), "bear");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
            equal(getenvInChild(pb,"QUUX"), "bear");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
            checkMapSanity(environ);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
            // Remove env var
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
            environ.remove("QUUX");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
            equal(environ.get("QUUX"), null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
            equal(getenvInChild(pb,"QUUX"), "null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
            checkMapSanity(environ);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
            // Remove non-existent env var
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
            environ.remove("QUUX");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
            equal(environ.get("QUUX"), null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
            equal(getenvInChild(pb,"QUUX"), "null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
            checkMapSanity(environ);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
        // Pass Empty environment to child
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
            ProcessBuilder pb = new ProcessBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
            pb.environment().clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
            equal(getenvInChild(pb), "");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
        // System.getenv() is read-only.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
        THROWS(UnsupportedOperationException.class,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
            new Fun(){void f(){ getenv().put("FOO","BAR");}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
            new Fun(){void f(){ getenv().remove("PATH");}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
            new Fun(){void f(){ getenv().keySet().remove("PATH");}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
            new Fun(){void f(){ getenv().values().remove("someValue");}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
            Collection<Map.Entry<String,String>> c = getenv().entrySet();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
            if (! c.isEmpty())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
                    c.iterator().next().setValue("foo");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
                    fail("Expected UnsupportedOperationException not thrown");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
                } catch (UnsupportedOperationException e) {} // OK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
        // System.getenv() always returns the same object in our implementation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
            check(System.getenv() == System.getenv());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
        // You can't create an env var name containing "=",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
        // or an env var name or value containing NUL.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
            final Map<String,String> m = new ProcessBuilder().environment();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
            THROWS(IllegalArgumentException.class,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
                new Fun(){void f(){ m.put("FOO=","BAR");}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
                new Fun(){void f(){ m.put("FOO\u0000","BAR");}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
                new Fun(){void f(){ m.put("FOO","BAR\u0000");}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
        // Commands must never be null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
        THROWS(NullPointerException.class,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
               new Fun(){void f(){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
                   new ProcessBuilder((List<String>)null);}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
               new Fun(){void f(){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
                   new ProcessBuilder().command((List<String>)null);}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
        // Put in a command; get the same one back out.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
            List<String> command = new ArrayList<String>();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
            ProcessBuilder pb = new ProcessBuilder(command);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
            check(pb.command() == command);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
            List<String> command2 = new ArrayList<String>(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
            command2.add("foo");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
            command2.add("bar");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
            pb.command(command2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
            check(pb.command() == command2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
            pb.command("foo", "bar");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
            check(pb.command() != command2 && pb.command().equals(command2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
            pb.command(command2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
            command2.add("baz");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
            equal(pb.command().get(2), "baz");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
        // Commands must contain at least one element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
        THROWS(IndexOutOfBoundsException.class,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
            new Fun() { void f() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
                new ProcessBuilder().start();}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
            new Fun() { void f() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
                new ProcessBuilder(new ArrayList<String>()).start();}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
            new Fun() { void f() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
                Runtime.getRuntime().exec(new String[]{});}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
        // Commands must not contain null elements at start() time.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
        THROWS(NullPointerException.class,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
            new Fun() { void f() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
                new ProcessBuilder("foo",null,"bar").start();}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
            new Fun() { void f() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
                new ProcessBuilder((String)null).start();}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
            new Fun() { void f() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
                new ProcessBuilder(new String[]{null}).start();}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
            new Fun() { void f() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
                new ProcessBuilder(new String[]{"foo",null,"bar"}).start();}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
        // Command lists are growable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
            new ProcessBuilder().command().add("foo");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
            new ProcessBuilder("bar").command().add("foo");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
            new ProcessBuilder(new String[]{"1","2"}).command().add("3");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
        // Nulls in environment updates generate NullPointerException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
            final Map<String,String> env = new ProcessBuilder().environment();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
            THROWS(NullPointerException.class,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
                new Fun(){void f(){ env.put("foo",null);}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
                new Fun(){void f(){ env.put(null,"foo");}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
                new Fun(){void f(){ env.remove(null);}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
                new Fun(){void f(){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
                    for (Map.Entry<String,String> e : env.entrySet())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
                        e.setValue(null);}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
                new Fun() { void f() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
                    Runtime.getRuntime().exec(new String[]{"foo"},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
                                              new String[]{null});}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
        // Non-String types in environment updates generate ClassCastException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
            final Map<String,String> env = new ProcessBuilder().environment();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
            THROWS(ClassCastException.class,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
                new Fun(){void f(){ env.remove(TRUE);}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
                new Fun(){void f(){ env.keySet().remove(TRUE);}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
                new Fun(){void f(){ env.values().remove(TRUE);}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
                new Fun(){void f(){ env.entrySet().remove(TRUE);}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
        // Check query operations on environment maps
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
            List<Map<String,String>> envs =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
                new ArrayList<Map<String,String>>(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
            envs.add(System.getenv());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
            envs.add(new ProcessBuilder().environment());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
            for (final Map<String,String> env : envs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
                //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
                // Nulls in environment queries are forbidden.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
                //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
                THROWS(NullPointerException.class,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
                    new Fun(){void f(){ getenv(null);}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
                    new Fun(){void f(){ env.get(null);}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
                    new Fun(){void f(){ env.containsKey(null);}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
                    new Fun(){void f(){ env.containsValue(null);}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
                    new Fun(){void f(){ env.keySet().contains(null);}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
                    new Fun(){void f(){ env.values().contains(null);}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
                //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
                // Non-String types in environment queries are forbidden.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
                //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
                THROWS(ClassCastException.class,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
                    new Fun(){void f(){ env.get(TRUE);}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
                    new Fun(){void f(){ env.containsKey(TRUE);}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
                    new Fun(){void f(){ env.containsValue(TRUE);}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
                    new Fun(){void f(){ env.keySet().contains(TRUE);}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
                    new Fun(){void f(){ env.values().contains(TRUE);}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
                //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
                // Illegal String values in environment queries are (grumble) OK
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
                //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
                equal(env.get("\u0000"), null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
                check(! env.containsKey("\u0000"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
                check(! env.containsValue("\u0000"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
                check(! env.keySet().contains("\u0000"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
                check(! env.values().contains("\u0000"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
            final Set<Map.Entry<String,String>> entrySet =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
                new ProcessBuilder().environment().entrySet();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
            THROWS(NullPointerException.class,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
                   new Fun(){void f(){ entrySet.contains(null);}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
            THROWS(ClassCastException.class,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
                new Fun(){void f(){ entrySet.contains(TRUE);}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
                new Fun(){void f(){
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
                    entrySet.contains(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
                        new SimpleImmutableEntry<Boolean,String>(TRUE,""));}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
            check(! entrySet.contains
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
                  (new SimpleImmutableEntry<String,String>("", "")));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
        // Put in a directory; get the same one back out.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
            ProcessBuilder pb = new ProcessBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
            File foo = new File("foo");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
            equal(pb.directory(), null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
            equal(pb.directory(foo).directory(), foo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
            equal(pb.directory(null).directory(), null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
        // If round-trip conversion works, check envvar pass-through to child
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
            testEncoding("ASCII",   "xyzzy");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
            testEncoding("Latin1",  "\u00f1\u00e1");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
            testEncoding("Unicode", "\u22f1\u11e1");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
        // A surprisingly large number of ways to delete an environment var.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
        testVariableDeleter(new EnvironmentFrobber() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
                public void doIt(Map<String,String> environ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
                    environ.remove("Foo");}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
        testVariableDeleter(new EnvironmentFrobber() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
                public void doIt(Map<String,String> environ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
                    environ.keySet().remove("Foo");}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
        testVariableDeleter(new EnvironmentFrobber() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
                public void doIt(Map<String,String> environ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
                    environ.values().remove("BAAR");}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
        testVariableDeleter(new EnvironmentFrobber() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
                public void doIt(Map<String,String> environ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
                    // Legally fabricate a ProcessEnvironment.StringEntry,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
                    // even though it's private.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
                    Map<String,String> environ2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
                        = new ProcessBuilder().environment();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
                    environ2.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
                    environ2.put("Foo","BAAR");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
                    // Subtlety alert.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
                    Map.Entry<String,String> e
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
                        = environ2.entrySet().iterator().next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
                    environ.entrySet().remove(e);}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
        testVariableDeleter(new EnvironmentFrobber() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
                public void doIt(Map<String,String> environ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
                    Map.Entry<String,String> victim = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
                    for (Map.Entry<String,String> e : environ.entrySet())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
                        if (e.getKey().equals("Foo"))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
                            victim = e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
                    if (victim != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
                        environ.entrySet().remove(victim);}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
        testVariableDeleter(new EnvironmentFrobber() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
                public void doIt(Map<String,String> environ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
                    Iterator<String> it = environ.keySet().iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
                    while (it.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
                        String val = it.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
                        if (val.equals("Foo"))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
                            it.remove();}}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
        testVariableDeleter(new EnvironmentFrobber() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
                public void doIt(Map<String,String> environ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
                    Iterator<Map.Entry<String,String>> it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
                        = environ.entrySet().iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
                    while (it.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
                        Map.Entry<String,String> e = it.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
                        if (e.getKey().equals("Foo"))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
                            it.remove();}}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
        testVariableDeleter(new EnvironmentFrobber() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
                public void doIt(Map<String,String> environ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
                    Iterator<String> it = environ.values().iterator();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
                    while (it.hasNext()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
                        String val = it.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
                        if (val.equals("BAAR"))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
                            it.remove();}}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
        // A surprisingly small number of ways to add an environment var.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
        testVariableAdder(new EnvironmentFrobber() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
                public void doIt(Map<String,String> environ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
                    environ.put("Foo","Bahrein");}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
        // A few ways to modify an environment var.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
        testVariableModifier(new EnvironmentFrobber() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
                public void doIt(Map<String,String> environ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
                    environ.put("Foo","NewValue");}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
        testVariableModifier(new EnvironmentFrobber() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
                public void doIt(Map<String,String> environ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
                    for (Map.Entry<String,String> e : environ.entrySet())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
                        if (e.getKey().equals("Foo"))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
                            e.setValue("NewValue");}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
        // Fiddle with environment sizes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
            Map<String,String> environ = new ProcessBuilder().environment();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
            int size = environ.size();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
            checkSizes(environ, size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
            environ.put("UnLiKeLYeNVIROmtNam", "someVal");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
            checkSizes(environ, size+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
            // Check for environment independence
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
            new ProcessBuilder().environment().clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
            environ.put("UnLiKeLYeNVIROmtNam", "someOtherVal");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
            checkSizes(environ, size+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
            environ.remove("UnLiKeLYeNVIROmtNam");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
            checkSizes(environ, size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
            environ.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
            checkSizes(environ, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
            environ.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
            checkSizes(environ, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
            environ = new ProcessBuilder().environment();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
            environ.keySet().clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
            checkSizes(environ, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
            environ = new ProcessBuilder().environment();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
            environ.entrySet().clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
            checkSizes(environ, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
            environ = new ProcessBuilder().environment();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
            environ.values().clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
            checkSizes(environ, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
        // Check that various map invariants hold
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
        checkMapSanity(new ProcessBuilder().environment());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
        checkMapSanity(System.getenv());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
        checkMapEquality(new ProcessBuilder().environment(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
                         new ProcessBuilder().environment());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
        // Check effects on external "env" command.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
            Set<String> env1 = new HashSet<String>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
                (Arrays.asList(nativeEnv((String[])null).split("\n")));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
            ProcessBuilder pb = new ProcessBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
            pb.environment().put("QwErTyUiOp","AsDfGhJk");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
            Set<String> env2 = new HashSet<String>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
                (Arrays.asList(nativeEnv(pb).split("\n")));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
            check(env2.size() == env1.size() + 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
            env1.add("QwErTyUiOp=AsDfGhJk");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
            check(env1.equals(env2));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
        // Test Runtime.exec(...envp...)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
        // Check for sort order of environment variables on Windows.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
            // '+' < 'A' < 'Z' < '_' < 'a' < 'z' < '~'
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
            String[]envp = {"FOO=BAR","BAZ=GORP","QUUX=",
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
                            "+=+", "_=_", "~=~"};
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
            String output = nativeEnv(envp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
            String expected = "+=+\nBAZ=GORP\nFOO=BAR\nQUUX=\n_=_\n~=~\n";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
            // On Windows, Java must keep the environment sorted.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
            // Order is random on Unix, so this test does the sort.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
            if (! Windows.is())
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
                output = sortByLinesWindowsly(output);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
            equal(output, expected);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
        // System.getenv() must be consistent with System.getenv(String)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
            for (Map.Entry<String,String> e : getenv().entrySet())
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
                equal(getenv(e.getKey()), e.getValue());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
        // Fiddle with working directory in child
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
            String canonicalUserDir =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
                new File(System.getProperty("user.dir")).getCanonicalPath();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
            String[] sdirs = new String[]
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
                {".", "..", "/", "/bin",
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
                 "C:", "c:", "C:/", "c:\\", "\\", "\\bin" };
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
            for (String sdir : sdirs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
                File dir = new File(sdir);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
                if (! (dir.isDirectory() && dir.exists()))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
                out.println("Testing directory " + dir);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
                dir = new File(dir.getCanonicalPath());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
                ProcessBuilder pb = new ProcessBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
                equal(pb.directory(), null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
                equal(pwdInChild(pb), canonicalUserDir);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
                pb.directory(dir);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
                equal(pb.directory(), dir);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
                equal(pwdInChild(pb), dir.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
                pb.directory(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
                equal(pb.directory(), null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
                equal(pwdInChild(pb), canonicalUserDir);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
                pb.directory(dir);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
        // Windows has tricky semi-case-insensitive semantics
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
        if (Windows.is())
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
                out.println("Running case insensitve variable tests");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
                for (String[] namePair :
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
                         new String[][]
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
                    { new String[]{"PATH","PaTh"},
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
                      new String[]{"home","HOME"},
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
                      new String[]{"SYSTEMROOT","SystemRoot"}}) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
                    check((getenv(namePair[0]) == null &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
                           getenv(namePair[1]) == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
                          ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
                          getenv(namePair[0]).equals(getenv(namePair[1])),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
                          "Windows environment variables are not case insensitive");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
            } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
        // Test proper Unicode child environment transfer
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
        if (UnicodeOS.is())
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
                ProcessBuilder pb = new ProcessBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
                pb.environment().put("\u1234","\u5678");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
                pb.environment().remove("PATH");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
                equal(getenvInChild1234(pb), "\u5678");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
            } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
        // Test Runtime.exec(...envp...) with envstrings with initial `='
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
            List<String> childArgs = new ArrayList<String>(javaChildArgs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
            childArgs.add("System.getenv()");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
            String[] cmdp = childArgs.toArray(new String[childArgs.size()]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
            String[] envp = {"=ExitValue=3", "=C:=\\"};
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
            Process p = Runtime.getRuntime().exec(cmdp, envp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
            String expected = Windows.is() ? "=C:=\\,=ExitValue=3," : "=C:=\\,";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
            equal(commandOutput(p), expected);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
            if (Windows.is()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
                ProcessBuilder pb = new ProcessBuilder(childArgs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
                pb.environment().clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
                pb.environment().put("=ExitValue", "3");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
                pb.environment().put("=C:", "\\");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
                equal(commandOutput(pb), expected);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
        // Test Runtime.exec(...envp...) with envstrings without any `='
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
            String[] cmdp = {"echo"};
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
            String[] envp = {"Hello", "World"}; // Yuck!
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
            Process p = Runtime.getRuntime().exec(cmdp, envp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
            equal(commandOutput(p), "\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
        // Test Runtime.exec(...envp...) with envstrings containing NULs
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
            List<String> childArgs = new ArrayList<String>(javaChildArgs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
            childArgs.add("System.getenv()");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
            String[] cmdp = childArgs.toArray(new String[childArgs.size()]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
            String[] envp = {"LC_ALL=C\u0000\u0000", // Yuck!
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
                             "FO\u0000=B\u0000R"};
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
            Process p = Runtime.getRuntime().exec(cmdp, envp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
            check(commandOutput(p).equals("LC_ALL=C,"),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
                  "Incorrect handling of envstrings containing NULs");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
        // Test the redirectErrorStream property
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
            ProcessBuilder pb = new ProcessBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
            equal(pb.redirectErrorStream(), false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
            equal(pb.redirectErrorStream(true), pb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
            equal(pb.redirectErrorStream(), true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
            equal(pb.redirectErrorStream(false), pb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
            equal(pb.redirectErrorStream(), false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
            List<String> childArgs = new ArrayList<String>(javaChildArgs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
            childArgs.add("OutErr");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
            ProcessBuilder pb = new ProcessBuilder(childArgs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
                ProcessResults r = run(pb.start());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
                equal(r.out(), "outout");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
                equal(r.err(), "errerr");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
            {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
                pb.redirectErrorStream(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
                ProcessResults r = run(pb.start());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
                equal(r.out(), "outerrouterr");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
                equal(r.err(), "");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
        if (! Windows.is() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
            new File("/bin/true").exists() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
            new File("/bin/false").exists()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
            //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
            // We can find true and false when PATH is null
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
            //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
                List<String> childArgs = new ArrayList<String>(javaChildArgs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
                childArgs.add("null PATH");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
                ProcessBuilder pb = new ProcessBuilder(childArgs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
                pb.environment().remove("PATH");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
                ProcessResults r = run(pb.start());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
                equal(r.out(), "");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
                equal(r.err(), "");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
                equal(r.exitValue(), 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
            } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
            //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
            // PATH search algorithm on Unix
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
            //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
                List<String> childArgs = new ArrayList<String>(javaChildArgs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
                childArgs.add("PATH search algorithm");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
                ProcessBuilder pb = new ProcessBuilder(childArgs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
                pb.environment().put("PATH", "dir1:dir2:");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
                ProcessResults r = run(pb.start());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
                equal(r.out(), "");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
                equal(r.err(), "");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
                equal(r.exitValue(), True.exitValue());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
            } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
            //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
            // Parent's, not child's PATH is used
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
            //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
                new File("suBdiR").mkdirs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1199
                copy("/bin/true", "suBdiR/unliKely");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1200
                final ProcessBuilder pb =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1201
                    new ProcessBuilder(new String[]{"unliKely"});
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1202
                pb.environment().put("PATH", "suBdiR");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1203
                THROWS(IOException.class,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1204
                       new Fun() {void f() throws Throwable {pb.start();}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
            } catch (Throwable t) { unexpected(t);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
            } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
                new File("suBdiR/unliKely").delete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
                new File("suBdiR").delete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
        // Attempt to start bogus program ""
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
            new ProcessBuilder("").start();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
            fail("Expected IOException not thrown");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1219
            String m = e.getMessage();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
            if (EnglishUnix.is() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1221
                ! matches(m, "No such file or directory"))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
                unexpected(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1224
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
        // Check that attempt to execute program name with funny
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
        // characters throws an exception containing those characters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
        for (String programName : new String[] {"\u00f0", "\u01f0"})
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
                new ProcessBuilder(programName).start();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
                fail("Expected IOException not thrown");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
            } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
                String m = e.getMessage();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
                Pattern p = Pattern.compile(programName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1236
                if (! matches(m, programName)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
                    || (EnglishUnix.is()
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
                        && ! matches(m, "No such file or directory")))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
                    unexpected(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
            } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
        // Attempt to start process in nonexistent directory fails.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1244
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1246
            new ProcessBuilder("echo")
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
                .directory(new File("UnLiKeLY"))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
                .start();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
            fail("Expected IOException not thrown");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1250
        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1251
            String m = e.getMessage();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1252
            if (! matches(m, "in directory")
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1253
                || (EnglishUnix.is() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1254
                    ! matches(m, "No such file or directory")))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1255
                unexpected(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1256
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1257
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1258
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1259
        // This would deadlock, if not for the fact that
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1260
        // interprocess pipe buffers are at least 4096 bytes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1261
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1262
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
            List<String> childArgs = new ArrayList<String>(javaChildArgs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1264
            childArgs.add("print4095");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1265
            Process p = new ProcessBuilder(childArgs).start();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1266
            print4095(p.getOutputStream()); // Might hang!
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1267
            p.waitFor();                    // Might hang!
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1268
            equal(p.exitValue(), 5);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1269
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1270
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1272
        // Attempt to start process with insufficient permissions fails.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1273
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1274
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1275
            new File("emptyCommand").delete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1276
            new FileOutputStream("emptyCommand").close();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1277
            new File("emptyCommand").setExecutable(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1278
            new ProcessBuilder("./emptyCommand").start();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1279
            fail("Expected IOException not thrown");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1280
        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1281
            new File("./emptyCommand").delete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1282
            String m = e.getMessage();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1283
            //e.printStackTrace();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1284
            if (EnglishUnix.is() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1285
                ! matches(m, "Permission denied"))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1286
                unexpected(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1287
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1288
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1289
        new File("emptyCommand").delete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1290
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1291
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1292
        // Check for correct security permission behavior
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1293
        //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1294
        final Policy policy = new Policy();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1295
        Policy.setPolicy(policy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1296
        System.setSecurityManager(new SecurityManager());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1297
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1298
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1299
            // No permissions required to CREATE a ProcessBuilder
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1300
            policy.setPermissions(/* Nothing */);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1301
            new ProcessBuilder("env").directory(null).directory();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1302
            new ProcessBuilder("env").directory(new File("dir")).directory();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1303
            new ProcessBuilder("env").command("??").command();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1304
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1305
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1306
        THROWS(SecurityException.class,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1307
            new Fun() { void f() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1308
                policy.setPermissions(/* Nothing */);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1309
                System.getenv("foo");}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1310
            new Fun() { void f() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1311
                policy.setPermissions(/* Nothing */);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1312
                System.getenv();}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1313
            new Fun() { void f() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1314
                policy.setPermissions(/* Nothing */);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1315
                new ProcessBuilder("echo").start();}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1316
            new Fun() { void f() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1317
                policy.setPermissions(/* Nothing */);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1318
                Runtime.getRuntime().exec("echo");}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1319
            new Fun() { void f() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1320
                policy.setPermissions(new RuntimePermission("getenv.bar"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1321
                System.getenv("foo");}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1322
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1323
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1324
            policy.setPermissions(new RuntimePermission("getenv.foo"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1325
            System.getenv("foo");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1326
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1327
            policy.setPermissions(new RuntimePermission("getenv.*"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1328
            System.getenv("foo");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1329
            System.getenv();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1330
            new ProcessBuilder().environment();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1331
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1332
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1333
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1334
        final Permission execPermission
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1335
            = new FilePermission("<<ALL FILES>>", "execute");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1336
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1337
        THROWS(SecurityException.class,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1338
            new Fun() { void f() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1339
                // environment permission by itself insufficient
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1340
                policy.setPermissions(new RuntimePermission("getenv.*"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1341
                ProcessBuilder pb = new ProcessBuilder("env");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1342
                pb.environment().put("foo","bar");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1343
                pb.start();}},
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1344
            new Fun() { void f() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1345
                 // exec permission by itself insufficient
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1346
                 policy.setPermissions(execPermission);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1347
                 ProcessBuilder pb = new ProcessBuilder("env");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1348
                 pb.environment().put("foo","bar");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1349
                 pb.start();}});
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1350
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1351
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1352
            // Both permissions? OK.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1353
            policy.setPermissions(new RuntimePermission("getenv.*"),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1354
                                  execPermission);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1355
            ProcessBuilder pb = new ProcessBuilder("env");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1356
            pb.environment().put("foo","bar");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1357
            pb.start();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1358
        } catch (IOException e) { // OK
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1359
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1360
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1361
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1362
            // Don't need environment permission unless READING environment
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1363
            policy.setPermissions(execPermission);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1364
            Runtime.getRuntime().exec("env", new String[]{});
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1365
        } catch (IOException e) { // OK
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1366
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1367
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1368
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1369
            // Don't need environment permission unless READING environment
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1370
            policy.setPermissions(execPermission);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1371
            new ProcessBuilder("env").start();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1372
        } catch (IOException e) { // OK
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1373
        } catch (Throwable t) { unexpected(t); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1374
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1375
        // Restore "normal" state without a security manager
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1376
        policy.setPermissions(new RuntimePermission("setSecurityManager"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1377
        System.setSecurityManager(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1378
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1379
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1380
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1381
    //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1382
    // A Policy class designed to make permissions fiddling very easy.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1383
    //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1384
    private static class Policy extends java.security.Policy {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1385
        private Permissions perms;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1386
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1387
        public void setPermissions(Permission...permissions) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1388
            perms = new Permissions();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1389
            for (Permission permission : permissions)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1390
                perms.add(permission);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1391
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1392
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1393
        public Policy() { setPermissions(/* Nothing */); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1394
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1395
        public PermissionCollection getPermissions(CodeSource cs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1396
            return perms;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1397
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1398
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1399
        public PermissionCollection getPermissions(ProtectionDomain pd) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1400
            return perms;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1401
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1402
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1403
        public boolean implies(ProtectionDomain pd, Permission p) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1404
            return perms.implies(p);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1405
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1406
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1407
        public void refresh() {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1408
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1409
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1410
    private static class StreamAccumulator extends Thread {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1411
        private final InputStream is;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1412
        private final StringBuilder sb = new StringBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1413
        private Throwable throwable = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1414
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1415
        public String result () throws Throwable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1416
            if (throwable != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1417
                throw throwable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1418
            return sb.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1419
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1420
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1421
        StreamAccumulator (InputStream is) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1422
            this.is = is;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1423
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1424
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1425
        public void run() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1426
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1427
                Reader r = new InputStreamReader(is);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1428
                char[] buf = new char[4096];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1429
                int n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1430
                while ((n = r.read(buf)) > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1431
                    sb.append(buf,0,n);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1432
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1433
            } catch (Throwable t) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1434
                throwable = t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1435
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1436
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1437
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1438
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1439
    private static ProcessResults run(Process p) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1440
        Throwable throwable = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1441
        int exitValue = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1442
        String out = "";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1443
        String err = "";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1444
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1445
        StreamAccumulator outAccumulator =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1446
            new StreamAccumulator(p.getInputStream());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1447
        StreamAccumulator errAccumulator =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1448
            new StreamAccumulator(p.getErrorStream());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1449
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1450
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1451
            outAccumulator.start();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1452
            errAccumulator.start();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1453
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1454
            exitValue = p.waitFor();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1455
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1456
            outAccumulator.join();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1457
            errAccumulator.join();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1458
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1459
            out = outAccumulator.result();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1460
            err = errAccumulator.result();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1461
        } catch (Throwable t) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1462
            throwable = t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1463
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1464
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1465
        return new ProcessResults(out, err, exitValue, throwable);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1466
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1467
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1468
    //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1469
    // Results of a command
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1470
    //----------------------------------------------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1471
    private static class ProcessResults {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1472
        private final String out;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1473
        private final String err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1474
        private final int exitValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1475
        private final Throwable throwable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1476
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1477
        public ProcessResults(String out,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1478
                              String err,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1479
                              int exitValue,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1480
                              Throwable throwable) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1481
            this.out = out;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1482
            this.err = err;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1483
            this.exitValue = exitValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1484
            this.throwable = throwable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1485
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1486
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1487
        public String out()          { return out; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1488
        public String err()          { return err; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1489
        public int exitValue()       { return exitValue; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1490
        public Throwable throwable() { return throwable; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1491
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1492
        public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1493
            StringBuilder sb = new StringBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1494
            sb.append("<STDOUT>\n" + out() + "</STDOUT>\n")
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1495
                .append("<STDERR>\n" + err() + "</STDERR>\n")
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1496
                .append("exitValue = " + exitValue + "\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1497
            if (throwable != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1498
                sb.append(throwable.getStackTrace());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1499
            return sb.toString();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1500
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1501
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1502
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1503
    //--------------------- Infrastructure ---------------------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1504
    static volatile int passed = 0, failed = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1505
    static void pass() {passed++;}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1506
    static void fail() {failed++; Thread.dumpStack();}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1507
    static void fail(String msg) {System.out.println(msg); fail();}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1508
    static void unexpected(Throwable t) {failed++; t.printStackTrace();}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1509
    static void check(boolean cond) {if (cond) pass(); else fail();}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1510
    static void check(boolean cond, String m) {if (cond) pass(); else fail(m);}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1511
    static void equal(Object x, Object y) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1512
        if (x == null ? y == null : x.equals(y)) pass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1513
        else fail(x + " not equal to " + y);}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1514
    public static void main(String[] args) throws Throwable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1515
        try {realMain(args);} catch (Throwable t) {unexpected(t);}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1516
        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1517
        if (failed > 0) throw new AssertionError("Some tests failed");}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1518
    private static abstract class Fun {abstract void f() throws Throwable;}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1519
    static void THROWS(Class<? extends Throwable> k, Fun... fs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1520
        for (Fun f : fs)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1521
            try { f.f(); fail("Expected " + k.getName() + " not thrown"); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1522
            catch (Throwable t) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1523
                if (k.isAssignableFrom(t.getClass())) pass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1524
                else unexpected(t);}}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1525
}