author | robm |
Mon, 20 Aug 2012 14:52:12 +0100 | |
changeset 13581 | b3fe3cd75b37 |
parent 13149 | 27d52f97a5cc |
child 14178 | f2c729b81c6a |
permissions | -rw-r--r-- |
2 | 1 |
/* |
12538
211d6e82fe51
7130404: [macosx] "os.arch" value should be "x86_64" for compatibility with Apple JDK6
jmelvin
parents:
12047
diff
changeset
|
2 |
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. |
2 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
7 |
* published by the Free Software Foundation. |
|
8 |
* |
|
9 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
10 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
11 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
12 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
13 |
* accompanied this code). |
|
14 |
* |
|
15 |
* You should have received a copy of the GNU General Public License version |
|
16 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
17 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
18 |
* |
|
5506 | 19 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 |
* or visit www.oracle.com if you need additional information or have any |
|
21 |
* questions. |
|
2 | 22 |
*/ |
23 |
||
24 |
/* |
|
25 |
* @test |
|
26 |
* @bug 4199068 4738465 4937983 4930681 4926230 4931433 4932663 4986689 |
|
27 |
* 5026830 5023243 5070673 4052517 4811767 6192449 6397034 6413313 |
|
3840
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
28 |
* 6464154 6523983 6206031 4960438 6631352 6631966 6850957 6850958 |
13149
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
29 |
* 4947220 7018606 7034570 4244896 |
2 | 30 |
* @summary Basic tests for Process and Environment Variable code |
5600
8ca34998a6b3
6943915: Adjust jdk/test/Makefile to deal with .dll and .so libraries needing execute permissions
ohair
parents:
5168
diff
changeset
|
31 |
* @run main/othervm/timeout=300 Basic |
2 | 32 |
* @author Martin Buchholz |
33 |
*/ |
|
34 |
||
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
35 |
import java.lang.ProcessBuilder.Redirect; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
36 |
import static java.lang.ProcessBuilder.Redirect.*; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
37 |
|
2 | 38 |
import java.io.*; |
39 |
import java.util.*; |
|
5786
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
40 |
import java.util.concurrent.CountDownLatch; |
13149
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
41 |
import java.util.concurrent.TimeUnit; |
2 | 42 |
import java.security.*; |
43 |
import java.util.regex.Pattern; |
|
12047
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
44 |
import java.util.regex.Matcher; |
2 | 45 |
import static java.lang.System.getenv; |
46 |
import static java.lang.System.out; |
|
47 |
import static java.lang.Boolean.TRUE; |
|
48 |
import static java.util.AbstractMap.SimpleImmutableEntry; |
|
49 |
||
50 |
public class Basic { |
|
51 |
||
8561
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
52 |
/* used for Windows only */ |
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
53 |
static final String systemRoot = System.getenv("SystemRoot"); |
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
54 |
|
12047
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
55 |
/* used for Mac OS X only */ |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
56 |
static final String cfUserTextEncoding = System.getenv("__CF_USER_TEXT_ENCODING"); |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
57 |
|
2 | 58 |
private static String commandOutput(Reader r) throws Throwable { |
59 |
StringBuilder sb = new StringBuilder(); |
|
60 |
int c; |
|
61 |
while ((c = r.read()) > 0) |
|
62 |
if (c != '\r') |
|
63 |
sb.append((char) c); |
|
64 |
return sb.toString(); |
|
65 |
} |
|
66 |
||
67 |
private static String commandOutput(Process p) throws Throwable { |
|
68 |
check(p.getInputStream() == p.getInputStream()); |
|
69 |
check(p.getOutputStream() == p.getOutputStream()); |
|
70 |
check(p.getErrorStream() == p.getErrorStream()); |
|
71 |
Reader r = new InputStreamReader(p.getInputStream(),"UTF-8"); |
|
72 |
String output = commandOutput(r); |
|
73 |
equal(p.waitFor(), 0); |
|
74 |
equal(p.exitValue(), 0); |
|
75 |
return output; |
|
76 |
} |
|
77 |
||
78 |
private static String commandOutput(ProcessBuilder pb) { |
|
79 |
try { |
|
80 |
return commandOutput(pb.start()); |
|
81 |
} catch (Throwable t) { |
|
82 |
String commandline = ""; |
|
83 |
for (String arg : pb.command()) |
|
84 |
commandline += " " + arg; |
|
85 |
System.out.println("Exception trying to run process: " + commandline); |
|
86 |
unexpected(t); |
|
87 |
return ""; |
|
88 |
} |
|
89 |
} |
|
90 |
||
91 |
private static String commandOutput(String...command) { |
|
92 |
try { |
|
93 |
return commandOutput(Runtime.getRuntime().exec(command)); |
|
94 |
} catch (Throwable t) { |
|
95 |
String commandline = ""; |
|
96 |
for (String arg : command) |
|
97 |
commandline += " " + arg; |
|
98 |
System.out.println("Exception trying to run process: " + commandline); |
|
99 |
unexpected(t); |
|
100 |
return ""; |
|
101 |
} |
|
102 |
} |
|
103 |
||
104 |
private static void checkCommandOutput(ProcessBuilder pb, |
|
105 |
String expected, |
|
106 |
String failureMsg) { |
|
107 |
String got = commandOutput(pb); |
|
108 |
check(got.equals(expected), |
|
109 |
failureMsg + "\n" + |
|
110 |
"Expected: \"" + expected + "\"\n" + |
|
111 |
"Got: \"" + got + "\""); |
|
112 |
} |
|
113 |
||
114 |
private static String absolutifyPath(String path) { |
|
115 |
StringBuilder sb = new StringBuilder(); |
|
116 |
for (String file : path.split(File.pathSeparator)) { |
|
117 |
if (sb.length() != 0) |
|
118 |
sb.append(File.pathSeparator); |
|
119 |
sb.append(new File(file).getAbsolutePath()); |
|
120 |
} |
|
121 |
return sb.toString(); |
|
122 |
} |
|
123 |
||
124 |
// compare windows-style, by canonicalizing to upper case, |
|
125 |
// not lower case as String.compareToIgnoreCase does |
|
126 |
private static class WindowsComparator |
|
127 |
implements Comparator<String> { |
|
128 |
public int compare(String x, String y) { |
|
129 |
return x.toUpperCase(Locale.US) |
|
130 |
.compareTo(y.toUpperCase(Locale.US)); |
|
131 |
} |
|
132 |
} |
|
133 |
||
134 |
private static String sortedLines(String lines) { |
|
135 |
String[] arr = lines.split("\n"); |
|
136 |
List<String> ls = new ArrayList<String>(); |
|
137 |
for (String s : arr) |
|
138 |
ls.add(s); |
|
139 |
Collections.sort(ls, new WindowsComparator()); |
|
140 |
StringBuilder sb = new StringBuilder(); |
|
141 |
for (String s : ls) |
|
142 |
sb.append(s + "\n"); |
|
143 |
return sb.toString(); |
|
144 |
} |
|
145 |
||
146 |
private static void compareLinesIgnoreCase(String lines1, String lines2) { |
|
147 |
if (! (sortedLines(lines1).equalsIgnoreCase(sortedLines(lines2)))) { |
|
148 |
String dashes = |
|
149 |
"-----------------------------------------------------"; |
|
150 |
out.println(dashes); |
|
151 |
out.print(sortedLines(lines1)); |
|
152 |
out.println(dashes); |
|
153 |
out.print(sortedLines(lines2)); |
|
154 |
out.println(dashes); |
|
155 |
out.println("sizes: " + sortedLines(lines1).length() + |
|
156 |
" " + sortedLines(lines2).length()); |
|
157 |
||
158 |
fail("Sorted string contents differ"); |
|
159 |
} |
|
160 |
} |
|
161 |
||
162 |
private static final Runtime runtime = Runtime.getRuntime(); |
|
163 |
||
164 |
private static final String[] winEnvCommand = {"cmd.exe", "/c", "set"}; |
|
165 |
||
166 |
private static String winEnvFilter(String env) { |
|
167 |
return env.replaceAll("\r", "") |
|
168 |
.replaceAll("(?m)^(?:COMSPEC|PROMPT|PATHEXT)=.*\n",""); |
|
169 |
} |
|
170 |
||
171 |
private static String unixEnvProg() { |
|
172 |
return new File("/usr/bin/env").canExecute() ? "/usr/bin/env" |
|
173 |
: "/bin/env"; |
|
174 |
} |
|
175 |
||
176 |
private static String nativeEnv(String[] env) { |
|
177 |
try { |
|
178 |
if (Windows.is()) { |
|
179 |
return winEnvFilter |
|
180 |
(commandOutput(runtime.exec(winEnvCommand, env))); |
|
181 |
} else { |
|
182 |
return commandOutput(runtime.exec(unixEnvProg(), env)); |
|
183 |
} |
|
184 |
} catch (Throwable t) { throw new Error(t); } |
|
185 |
} |
|
186 |
||
187 |
private static String nativeEnv(ProcessBuilder pb) { |
|
188 |
try { |
|
189 |
if (Windows.is()) { |
|
190 |
pb.command(winEnvCommand); |
|
191 |
return winEnvFilter(commandOutput(pb)); |
|
192 |
} else { |
|
193 |
pb.command(new String[]{unixEnvProg()}); |
|
194 |
return commandOutput(pb); |
|
195 |
} |
|
196 |
} catch (Throwable t) { throw new Error(t); } |
|
197 |
} |
|
198 |
||
199 |
private static void checkSizes(Map<String,String> environ, int size) { |
|
200 |
try { |
|
201 |
equal(size, environ.size()); |
|
202 |
equal(size, environ.entrySet().size()); |
|
203 |
equal(size, environ.keySet().size()); |
|
204 |
equal(size, environ.values().size()); |
|
205 |
||
206 |
boolean isEmpty = (size == 0); |
|
207 |
equal(isEmpty, environ.isEmpty()); |
|
208 |
equal(isEmpty, environ.entrySet().isEmpty()); |
|
209 |
equal(isEmpty, environ.keySet().isEmpty()); |
|
210 |
equal(isEmpty, environ.values().isEmpty()); |
|
211 |
} catch (Throwable t) { unexpected(t); } |
|
212 |
} |
|
213 |
||
214 |
private interface EnvironmentFrobber { |
|
215 |
void doIt(Map<String,String> environ); |
|
216 |
} |
|
217 |
||
218 |
private static void testVariableDeleter(EnvironmentFrobber fooDeleter) { |
|
219 |
try { |
|
220 |
Map<String,String> environ = new ProcessBuilder().environment(); |
|
221 |
environ.put("Foo", "BAAR"); |
|
222 |
fooDeleter.doIt(environ); |
|
223 |
equal(environ.get("Foo"), null); |
|
224 |
equal(environ.remove("Foo"), null); |
|
225 |
} catch (Throwable t) { unexpected(t); } |
|
226 |
} |
|
227 |
||
228 |
private static void testVariableAdder(EnvironmentFrobber fooAdder) { |
|
229 |
try { |
|
230 |
Map<String,String> environ = new ProcessBuilder().environment(); |
|
231 |
environ.remove("Foo"); |
|
232 |
fooAdder.doIt(environ); |
|
233 |
equal(environ.get("Foo"), "Bahrein"); |
|
234 |
} catch (Throwable t) { unexpected(t); } |
|
235 |
} |
|
236 |
||
237 |
private static void testVariableModifier(EnvironmentFrobber fooModifier) { |
|
238 |
try { |
|
239 |
Map<String,String> environ = new ProcessBuilder().environment(); |
|
240 |
environ.put("Foo","OldValue"); |
|
241 |
fooModifier.doIt(environ); |
|
242 |
equal(environ.get("Foo"), "NewValue"); |
|
243 |
} catch (Throwable t) { unexpected(t); } |
|
244 |
} |
|
245 |
||
246 |
private static void printUTF8(String s) throws IOException { |
|
247 |
out.write(s.getBytes("UTF-8")); |
|
248 |
} |
|
249 |
||
250 |
private static String getenvAsString(Map<String,String> environment) { |
|
251 |
StringBuilder sb = new StringBuilder(); |
|
12882
35d381df9422
7174723: TEST_BUG: java/lang/ProcessBuilder/Basic.java failing [win]
alanb
parents:
12538
diff
changeset
|
252 |
environment = new TreeMap<>(environment); |
2 | 253 |
for (Map.Entry<String,String> e : environment.entrySet()) |
254 |
// Ignore magic environment variables added by the launcher |
|
255 |
if (! e.getKey().equals("NLSPATH") && |
|
256 |
! e.getKey().equals("XFILESEARCHPATH") && |
|
257 |
! e.getKey().equals("LD_LIBRARY_PATH")) |
|
258 |
sb.append(e.getKey()) |
|
259 |
.append('=') |
|
260 |
.append(e.getValue()) |
|
261 |
.append(','); |
|
262 |
return sb.toString(); |
|
263 |
} |
|
264 |
||
5786
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
265 |
static void print4095(OutputStream s, byte b) throws Throwable { |
2 | 266 |
byte[] bytes = new byte[4095]; |
5786
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
267 |
Arrays.fill(bytes, b); |
2 | 268 |
s.write(bytes); // Might hang! |
269 |
} |
|
270 |
||
2946
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
271 |
static void checkPermissionDenied(ProcessBuilder pb) { |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
272 |
try { |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
273 |
pb.start(); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
274 |
fail("Expected IOException not thrown"); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
275 |
} catch (IOException e) { |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
276 |
String m = e.getMessage(); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
277 |
if (EnglishUnix.is() && |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
278 |
! matches(m, "Permission denied")) |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
279 |
unexpected(e); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
280 |
} catch (Throwable t) { unexpected(t); } |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
281 |
} |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
282 |
|
2 | 283 |
public static class JavaChild { |
284 |
public static void main(String args[]) throws Throwable { |
|
285 |
String action = args[0]; |
|
5786
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
286 |
if (action.equals("sleep")) { |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
287 |
Thread.sleep(10 * 60 * 1000L); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
288 |
} else if (action.equals("testIO")) { |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
289 |
String expected = "standard input"; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
290 |
char[] buf = new char[expected.length()+1]; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
291 |
int n = new InputStreamReader(System.in).read(buf,0,buf.length); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
292 |
if (n != expected.length()) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
293 |
System.exit(5); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
294 |
if (! new String(buf,0,n).equals(expected)) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
295 |
System.exit(5); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
296 |
System.err.print("standard error"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
297 |
System.out.print("standard output"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
298 |
} else if (action.equals("testInheritIO")) { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
299 |
List<String> childArgs = new ArrayList<String>(javaChildArgs); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
300 |
childArgs.add("testIO"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
301 |
ProcessBuilder pb = new ProcessBuilder(childArgs); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
302 |
pb.inheritIO(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
303 |
ProcessResults r = run(pb); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
304 |
if (! r.out().equals("")) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
305 |
System.exit(7); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
306 |
if (! r.err().equals("")) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
307 |
System.exit(8); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
308 |
if (r.exitValue() != 0) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
309 |
System.exit(9); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
310 |
} else if (action.equals("System.getenv(String)")) { |
2 | 311 |
String val = System.getenv(args[1]); |
312 |
printUTF8(val == null ? "null" : val); |
|
313 |
} else if (action.equals("System.getenv(\\u1234)")) { |
|
314 |
String val = System.getenv("\u1234"); |
|
315 |
printUTF8(val == null ? "null" : val); |
|
316 |
} else if (action.equals("System.getenv()")) { |
|
317 |
printUTF8(getenvAsString(System.getenv())); |
|
3840
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
318 |
} else if (action.equals("ArrayOOME")) { |
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
319 |
Object dummy; |
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
320 |
switch(new Random().nextInt(3)) { |
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
321 |
case 0: dummy = new Integer[Integer.MAX_VALUE]; break; |
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
322 |
case 1: dummy = new double[Integer.MAX_VALUE]; break; |
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
323 |
case 2: dummy = new byte[Integer.MAX_VALUE][]; break; |
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
324 |
default: throw new InternalError(); |
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
325 |
} |
2 | 326 |
} else if (action.equals("pwd")) { |
327 |
printUTF8(new File(System.getProperty("user.dir")) |
|
328 |
.getCanonicalPath()); |
|
329 |
} else if (action.equals("print4095")) { |
|
5786
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
330 |
print4095(System.out, (byte) '!'); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
331 |
print4095(System.err, (byte) 'E'); |
2 | 332 |
System.exit(5); |
333 |
} else if (action.equals("OutErr")) { |
|
334 |
// You might think the system streams would be |
|
335 |
// buffered, and in fact they are implemented using |
|
336 |
// BufferedOutputStream, but each and every print |
|
337 |
// causes immediate operating system I/O. |
|
338 |
System.out.print("out"); |
|
339 |
System.err.print("err"); |
|
340 |
System.out.print("out"); |
|
341 |
System.err.print("err"); |
|
342 |
} else if (action.equals("null PATH")) { |
|
343 |
equal(System.getenv("PATH"), null); |
|
344 |
check(new File("/bin/true").exists()); |
|
345 |
check(new File("/bin/false").exists()); |
|
346 |
ProcessBuilder pb1 = new ProcessBuilder(); |
|
347 |
ProcessBuilder pb2 = new ProcessBuilder(); |
|
348 |
pb2.environment().put("PATH", "anyOldPathIgnoredAnyways"); |
|
349 |
ProcessResults r; |
|
350 |
||
351 |
for (final ProcessBuilder pb : |
|
352 |
new ProcessBuilder[] {pb1, pb2}) { |
|
353 |
pb.command("true"); |
|
2946
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
354 |
equal(run(pb).exitValue(), True.exitValue()); |
2 | 355 |
|
356 |
pb.command("false"); |
|
2946
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
357 |
equal(run(pb).exitValue(), False.exitValue()); |
2 | 358 |
} |
359 |
||
360 |
if (failed != 0) throw new Error("null PATH"); |
|
361 |
} else if (action.equals("PATH search algorithm")) { |
|
362 |
equal(System.getenv("PATH"), "dir1:dir2:"); |
|
363 |
check(new File("/bin/true").exists()); |
|
364 |
check(new File("/bin/false").exists()); |
|
365 |
String[] cmd = {"prog"}; |
|
366 |
ProcessBuilder pb1 = new ProcessBuilder(cmd); |
|
367 |
ProcessBuilder pb2 = new ProcessBuilder(cmd); |
|
368 |
ProcessBuilder pb3 = new ProcessBuilder(cmd); |
|
369 |
pb2.environment().put("PATH", "anyOldPathIgnoredAnyways"); |
|
370 |
pb3.environment().remove("PATH"); |
|
371 |
||
372 |
for (final ProcessBuilder pb : |
|
373 |
new ProcessBuilder[] {pb1, pb2, pb3}) { |
|
374 |
try { |
|
375 |
// Not on PATH at all; directories don't exist |
|
376 |
try { |
|
377 |
pb.start(); |
|
378 |
fail("Expected IOException not thrown"); |
|
379 |
} catch (IOException e) { |
|
380 |
String m = e.getMessage(); |
|
381 |
if (EnglishUnix.is() && |
|
382 |
! matches(m, "No such file")) |
|
383 |
unexpected(e); |
|
384 |
} catch (Throwable t) { unexpected(t); } |
|
385 |
||
386 |
// Not on PATH at all; directories exist |
|
387 |
new File("dir1").mkdirs(); |
|
388 |
new File("dir2").mkdirs(); |
|
389 |
try { |
|
390 |
pb.start(); |
|
391 |
fail("Expected IOException not thrown"); |
|
392 |
} catch (IOException e) { |
|
393 |
String m = e.getMessage(); |
|
394 |
if (EnglishUnix.is() && |
|
395 |
! matches(m, "No such file")) |
|
396 |
unexpected(e); |
|
397 |
} catch (Throwable t) { unexpected(t); } |
|
398 |
||
399 |
// Can't execute a directory -- permission denied |
|
400 |
// Report EACCES errno |
|
401 |
new File("dir1/prog").mkdirs(); |
|
2946
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
402 |
checkPermissionDenied(pb); |
2 | 403 |
|
404 |
// continue searching if EACCES |
|
405 |
copy("/bin/true", "dir2/prog"); |
|
2946
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
406 |
equal(run(pb).exitValue(), True.exitValue()); |
2 | 407 |
new File("dir1/prog").delete(); |
408 |
new File("dir2/prog").delete(); |
|
409 |
||
410 |
new File("dir2/prog").mkdirs(); |
|
411 |
copy("/bin/true", "dir1/prog"); |
|
2946
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
412 |
equal(run(pb).exitValue(), True.exitValue()); |
2 | 413 |
|
2946
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
414 |
// Check empty PATH component means current directory. |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
415 |
// |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
416 |
// While we're here, let's test different kinds of |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
417 |
// Unix executables, and PATH vs explicit searching. |
2 | 418 |
new File("dir1/prog").delete(); |
419 |
new File("dir2/prog").delete(); |
|
2946
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
420 |
for (String[] command : |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
421 |
new String[][] { |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
422 |
new String[] {"./prog"}, |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
423 |
cmd}) { |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
424 |
pb.command(command); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
425 |
File prog = new File("./prog"); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
426 |
// "Normal" binaries |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
427 |
copy("/bin/true", "./prog"); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
428 |
equal(run(pb).exitValue(), |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
429 |
True.exitValue()); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
430 |
copy("/bin/false", "./prog"); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
431 |
equal(run(pb).exitValue(), |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
432 |
False.exitValue()); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
433 |
prog.delete(); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
434 |
// Interpreter scripts with #! |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
435 |
setFileContents(prog, "#!/bin/true\n"); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
436 |
prog.setExecutable(true); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
437 |
equal(run(pb).exitValue(), |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
438 |
True.exitValue()); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
439 |
prog.delete(); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
440 |
setFileContents(prog, "#!/bin/false\n"); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
441 |
prog.setExecutable(true); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
442 |
equal(run(pb).exitValue(), |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
443 |
False.exitValue()); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
444 |
// Traditional shell scripts without #! |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
445 |
setFileContents(prog, "exec /bin/true\n"); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
446 |
prog.setExecutable(true); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
447 |
equal(run(pb).exitValue(), |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
448 |
True.exitValue()); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
449 |
prog.delete(); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
450 |
setFileContents(prog, "exec /bin/false\n"); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
451 |
prog.setExecutable(true); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
452 |
equal(run(pb).exitValue(), |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
453 |
False.exitValue()); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
454 |
prog.delete(); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
455 |
} |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
456 |
|
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
457 |
// Test Unix interpreter scripts |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
458 |
File dir1Prog = new File("dir1/prog"); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
459 |
dir1Prog.delete(); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
460 |
pb.command(new String[] {"prog", "world"}); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
461 |
setFileContents(dir1Prog, "#!/bin/echo hello\n"); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
462 |
checkPermissionDenied(pb); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
463 |
dir1Prog.setExecutable(true); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
464 |
equal(run(pb).out(), "hello dir1/prog world\n"); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
465 |
equal(run(pb).exitValue(), True.exitValue()); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
466 |
dir1Prog.delete(); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
467 |
pb.command(cmd); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
468 |
|
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
469 |
// Test traditional shell scripts without #! |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
470 |
setFileContents(dir1Prog, "/bin/echo \"$@\"\n"); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
471 |
pb.command(new String[] {"prog", "hello", "world"}); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
472 |
checkPermissionDenied(pb); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
473 |
dir1Prog.setExecutable(true); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
474 |
equal(run(pb).out(), "hello world\n"); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
475 |
equal(run(pb).exitValue(), True.exitValue()); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
476 |
dir1Prog.delete(); |
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
477 |
pb.command(cmd); |
2 | 478 |
|
479 |
// If prog found on both parent and child's PATH, |
|
480 |
// parent's is used. |
|
481 |
new File("dir1/prog").delete(); |
|
482 |
new File("dir2/prog").delete(); |
|
483 |
new File("prog").delete(); |
|
484 |
new File("dir3").mkdirs(); |
|
485 |
copy("/bin/true", "dir1/prog"); |
|
486 |
copy("/bin/false", "dir3/prog"); |
|
487 |
pb.environment().put("PATH","dir3"); |
|
2946
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
488 |
equal(run(pb).exitValue(), True.exitValue()); |
2 | 489 |
copy("/bin/true", "dir3/prog"); |
490 |
copy("/bin/false", "dir1/prog"); |
|
2946
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
491 |
equal(run(pb).exitValue(), False.exitValue()); |
2 | 492 |
|
493 |
} finally { |
|
494 |
// cleanup |
|
495 |
new File("dir1/prog").delete(); |
|
496 |
new File("dir2/prog").delete(); |
|
497 |
new File("dir3/prog").delete(); |
|
498 |
new File("dir1").delete(); |
|
499 |
new File("dir2").delete(); |
|
500 |
new File("dir3").delete(); |
|
501 |
new File("prog").delete(); |
|
502 |
} |
|
503 |
} |
|
504 |
||
505 |
if (failed != 0) throw new Error("PATH search algorithm"); |
|
506 |
} |
|
507 |
else throw new Error("JavaChild invocation error"); |
|
508 |
} |
|
509 |
} |
|
510 |
||
511 |
private static void copy(String src, String dst) { |
|
512 |
system("/bin/cp", "-fp", src, dst); |
|
513 |
} |
|
514 |
||
515 |
private static void system(String... command) { |
|
516 |
try { |
|
517 |
ProcessBuilder pb = new ProcessBuilder(command); |
|
518 |
ProcessResults r = run(pb.start()); |
|
519 |
equal(r.exitValue(), 0); |
|
520 |
equal(r.out(), ""); |
|
521 |
equal(r.err(), ""); |
|
522 |
} catch (Throwable t) { unexpected(t); } |
|
523 |
} |
|
524 |
||
525 |
private static String javaChildOutput(ProcessBuilder pb, String...args) { |
|
526 |
List<String> list = new ArrayList<String>(javaChildArgs); |
|
527 |
for (String arg : args) |
|
528 |
list.add(arg); |
|
529 |
pb.command(list); |
|
530 |
return commandOutput(pb); |
|
531 |
} |
|
532 |
||
533 |
private static String getenvInChild(ProcessBuilder pb) { |
|
534 |
return javaChildOutput(pb, "System.getenv()"); |
|
535 |
} |
|
536 |
||
537 |
private static String getenvInChild1234(ProcessBuilder pb) { |
|
538 |
return javaChildOutput(pb, "System.getenv(\\u1234)"); |
|
539 |
} |
|
540 |
||
541 |
private static String getenvInChild(ProcessBuilder pb, String name) { |
|
542 |
return javaChildOutput(pb, "System.getenv(String)", name); |
|
543 |
} |
|
544 |
||
545 |
private static String pwdInChild(ProcessBuilder pb) { |
|
546 |
return javaChildOutput(pb, "pwd"); |
|
547 |
} |
|
548 |
||
549 |
private static final String javaExe = |
|
550 |
System.getProperty("java.home") + |
|
551 |
File.separator + "bin" + File.separator + "java"; |
|
552 |
||
553 |
private static final String classpath = |
|
554 |
System.getProperty("java.class.path"); |
|
555 |
||
556 |
private static final List<String> javaChildArgs = |
|
557 |
Arrays.asList(new String[] |
|
558 |
{ javaExe, "-classpath", absolutifyPath(classpath), |
|
559 |
"Basic$JavaChild"}); |
|
560 |
||
561 |
private static void testEncoding(String encoding, String tested) { |
|
562 |
try { |
|
563 |
// If round trip conversion works, should be able to set env vars |
|
564 |
// correctly in child. |
|
565 |
if (new String(tested.getBytes()).equals(tested)) { |
|
566 |
out.println("Testing " + encoding + " environment values"); |
|
567 |
ProcessBuilder pb = new ProcessBuilder(); |
|
568 |
pb.environment().put("ASCIINAME",tested); |
|
569 |
equal(getenvInChild(pb,"ASCIINAME"), tested); |
|
570 |
} |
|
571 |
} catch (Throwable t) { unexpected(t); } |
|
572 |
} |
|
573 |
||
574 |
static class Windows { |
|
575 |
public static boolean is() { return is; } |
|
576 |
private static final boolean is = |
|
577 |
System.getProperty("os.name").startsWith("Windows"); |
|
578 |
} |
|
579 |
||
580 |
static class Unix { |
|
581 |
public static boolean is() { return is; } |
|
582 |
private static final boolean is = |
|
583 |
(! Windows.is() && |
|
584 |
new File("/bin/sh").exists() && |
|
585 |
new File("/bin/true").exists() && |
|
586 |
new File("/bin/false").exists()); |
|
587 |
} |
|
588 |
||
589 |
static class UnicodeOS { |
|
590 |
public static boolean is() { return is; } |
|
591 |
private static final String osName = System.getProperty("os.name"); |
|
592 |
private static final boolean is = |
|
593 |
// MacOS X would probably also qualify |
|
594 |
osName.startsWith("Windows") && |
|
595 |
! osName.startsWith("Windows 9") && |
|
596 |
! osName.equals("Windows Me"); |
|
597 |
} |
|
598 |
||
12047
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
599 |
static class MacOSX { |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
600 |
public static boolean is() { return is; } |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
601 |
private static final String osName = System.getProperty("os.name"); |
12538
211d6e82fe51
7130404: [macosx] "os.arch" value should be "x86_64" for compatibility with Apple JDK6
jmelvin
parents:
12047
diff
changeset
|
602 |
private static final boolean is = osName.contains("OS X"); |
12047
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
603 |
} |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
604 |
|
2 | 605 |
static class True { |
606 |
public static int exitValue() { return 0; } |
|
607 |
} |
|
608 |
||
609 |
private static class False { |
|
610 |
public static int exitValue() { return exitValue; } |
|
611 |
private static final int exitValue = exitValue0(); |
|
612 |
private static int exitValue0() { |
|
613 |
// /bin/false returns an *unspecified* non-zero number. |
|
614 |
try { |
|
615 |
if (! Unix.is()) |
|
616 |
return -1; |
|
617 |
else { |
|
618 |
int rc = new ProcessBuilder("/bin/false") |
|
619 |
.start().waitFor(); |
|
620 |
check(rc != 0); |
|
621 |
return rc; |
|
622 |
} |
|
623 |
} catch (Throwable t) { unexpected(t); return -1; } |
|
624 |
} |
|
625 |
} |
|
626 |
||
627 |
static class EnglishUnix { |
|
628 |
private final static Boolean is = |
|
629 |
(! Windows.is() && isEnglish("LANG") && isEnglish("LC_ALL")); |
|
630 |
||
631 |
private static boolean isEnglish(String envvar) { |
|
632 |
String val = getenv(envvar); |
|
633 |
return (val == null) || val.matches("en.*"); |
|
634 |
} |
|
635 |
||
636 |
/** Returns true if we can expect English OS error strings */ |
|
637 |
static boolean is() { return is; } |
|
638 |
} |
|
639 |
||
13149
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
640 |
static class DelegatingProcess extends Process { |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
641 |
final Process p; |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
642 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
643 |
DelegatingProcess(Process p) { |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
644 |
this.p = p; |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
645 |
} |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
646 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
647 |
@Override |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
648 |
public void destroy() { |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
649 |
p.destroy(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
650 |
} |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
651 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
652 |
@Override |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
653 |
public int exitValue() { |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
654 |
return p.exitValue(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
655 |
} |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
656 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
657 |
@Override |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
658 |
public int waitFor() throws InterruptedException { |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
659 |
return p.waitFor(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
660 |
} |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
661 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
662 |
@Override |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
663 |
public OutputStream getOutputStream() { |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
664 |
return p.getOutputStream(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
665 |
} |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
666 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
667 |
@Override |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
668 |
public InputStream getInputStream() { |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
669 |
return p.getInputStream(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
670 |
} |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
671 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
672 |
@Override |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
673 |
public InputStream getErrorStream() { |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
674 |
return p.getErrorStream(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
675 |
} |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
676 |
} |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
677 |
|
2 | 678 |
private static boolean matches(String str, String regex) { |
679 |
return Pattern.compile(regex).matcher(str).find(); |
|
680 |
} |
|
681 |
||
12047
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
682 |
private static String matchAndExtract(String str, String regex) { |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
683 |
Matcher matcher = Pattern.compile(regex).matcher(str); |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
684 |
if (matcher.find()) { |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
685 |
return matcher.group(); |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
686 |
} else { |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
687 |
return ""; |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
688 |
} |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
689 |
} |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
690 |
|
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
691 |
/* Only used for Mac OS X -- |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
692 |
* Mac OS X (may) add the variable __CF_USER_TEXT_ENCODING to an empty |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
693 |
* environment. The environment variable JAVA_MAIN_CLASS_<pid> may also |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
694 |
* be set in Mac OS X. |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
695 |
* Remove them both from the list of env variables |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
696 |
*/ |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
697 |
private static String removeMacExpectedVars(String vars) { |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
698 |
// Check for __CF_USER_TEXT_ENCODING |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
699 |
String cleanedVars = vars.replace("__CF_USER_TEXT_ENCODING=" |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
700 |
+cfUserTextEncoding+",",""); |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
701 |
// Check for JAVA_MAIN_CLASS_<pid> |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
702 |
String javaMainClassStr |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
703 |
= matchAndExtract(cleanedVars, |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
704 |
"JAVA_MAIN_CLASS_\\d+=Basic.JavaChild,"); |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
705 |
return cleanedVars.replace(javaMainClassStr,""); |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
706 |
} |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
707 |
|
2 | 708 |
private static String sortByLinesWindowsly(String text) { |
709 |
String[] lines = text.split("\n"); |
|
710 |
Arrays.sort(lines, new WindowsComparator()); |
|
711 |
StringBuilder sb = new StringBuilder(); |
|
712 |
for (String line : lines) |
|
713 |
sb.append(line).append("\n"); |
|
714 |
return sb.toString(); |
|
715 |
} |
|
716 |
||
717 |
private static void checkMapSanity(Map<String,String> map) { |
|
718 |
try { |
|
719 |
Set<String> keySet = map.keySet(); |
|
720 |
Collection<String> values = map.values(); |
|
721 |
Set<Map.Entry<String,String>> entrySet = map.entrySet(); |
|
722 |
||
723 |
equal(entrySet.size(), keySet.size()); |
|
724 |
equal(entrySet.size(), values.size()); |
|
725 |
||
726 |
StringBuilder s1 = new StringBuilder(); |
|
727 |
for (Map.Entry<String,String> e : entrySet) |
|
728 |
s1.append(e.getKey() + "=" + e.getValue() + "\n"); |
|
729 |
||
730 |
StringBuilder s2 = new StringBuilder(); |
|
731 |
for (String var : keySet) |
|
732 |
s2.append(var + "=" + map.get(var) + "\n"); |
|
733 |
||
734 |
equal(s1.toString(), s2.toString()); |
|
735 |
||
736 |
Iterator<String> kIter = keySet.iterator(); |
|
737 |
Iterator<String> vIter = values.iterator(); |
|
738 |
Iterator<Map.Entry<String,String>> eIter = entrySet.iterator(); |
|
739 |
||
740 |
while (eIter.hasNext()) { |
|
741 |
Map.Entry<String,String> entry = eIter.next(); |
|
742 |
String key = kIter.next(); |
|
743 |
String value = vIter.next(); |
|
744 |
check(entrySet.contains(entry)); |
|
745 |
check(keySet.contains(key)); |
|
746 |
check(values.contains(value)); |
|
747 |
check(map.containsKey(key)); |
|
748 |
check(map.containsValue(value)); |
|
749 |
equal(entry.getKey(), key); |
|
750 |
equal(entry.getValue(), value); |
|
751 |
} |
|
752 |
check(! kIter.hasNext() && |
|
753 |
! vIter.hasNext()); |
|
754 |
||
755 |
} catch (Throwable t) { unexpected(t); } |
|
756 |
} |
|
757 |
||
758 |
private static void checkMapEquality(Map<String,String> map1, |
|
759 |
Map<String,String> map2) { |
|
760 |
try { |
|
761 |
equal(map1.size(), map2.size()); |
|
762 |
equal(map1.isEmpty(), map2.isEmpty()); |
|
763 |
for (String key : map1.keySet()) { |
|
764 |
equal(map1.get(key), map2.get(key)); |
|
765 |
check(map2.keySet().contains(key)); |
|
766 |
} |
|
767 |
equal(map1, map2); |
|
768 |
equal(map2, map1); |
|
769 |
equal(map1.entrySet(), map2.entrySet()); |
|
770 |
equal(map2.entrySet(), map1.entrySet()); |
|
771 |
equal(map1.keySet(), map2.keySet()); |
|
772 |
equal(map2.keySet(), map1.keySet()); |
|
773 |
||
774 |
equal(map1.hashCode(), map2.hashCode()); |
|
775 |
equal(map1.entrySet().hashCode(), map2.entrySet().hashCode()); |
|
776 |
equal(map1.keySet().hashCode(), map2.keySet().hashCode()); |
|
777 |
} catch (Throwable t) { unexpected(t); } |
|
778 |
} |
|
779 |
||
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
780 |
static void checkRedirects(ProcessBuilder pb, |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
781 |
Redirect in, Redirect out, Redirect err) { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
782 |
equal(pb.redirectInput(), in); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
783 |
equal(pb.redirectOutput(), out); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
784 |
equal(pb.redirectError(), err); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
785 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
786 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
787 |
static void redirectIO(ProcessBuilder pb, |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
788 |
Redirect in, Redirect out, Redirect err) { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
789 |
pb.redirectInput(in); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
790 |
pb.redirectOutput(out); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
791 |
pb.redirectError(err); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
792 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
793 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
794 |
static void setFileContents(File file, String contents) { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
795 |
try { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
796 |
Writer w = new FileWriter(file); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
797 |
w.write(contents); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
798 |
w.close(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
799 |
} catch (Throwable t) { unexpected(t); } |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
800 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
801 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
802 |
static String fileContents(File file) { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
803 |
try { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
804 |
Reader r = new FileReader(file); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
805 |
StringBuilder sb = new StringBuilder(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
806 |
char[] buffer = new char[1024]; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
807 |
int n; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
808 |
while ((n = r.read(buffer)) != -1) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
809 |
sb.append(buffer,0,n); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
810 |
r.close(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
811 |
return new String(sb); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
812 |
} catch (Throwable t) { unexpected(t); return ""; } |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
813 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
814 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
815 |
static void testIORedirection() throws Throwable { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
816 |
final File ifile = new File("ifile"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
817 |
final File ofile = new File("ofile"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
818 |
final File efile = new File("efile"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
819 |
ifile.delete(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
820 |
ofile.delete(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
821 |
efile.delete(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
822 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
823 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
824 |
// Check mutual inequality of different types of Redirect |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
825 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
826 |
Redirect[] redirects = |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
827 |
{ PIPE, |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
828 |
INHERIT, |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
829 |
Redirect.from(ifile), |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
830 |
Redirect.to(ifile), |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
831 |
Redirect.appendTo(ifile), |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
832 |
Redirect.from(ofile), |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
833 |
Redirect.to(ofile), |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
834 |
Redirect.appendTo(ofile), |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
835 |
}; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
836 |
for (int i = 0; i < redirects.length; i++) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
837 |
for (int j = 0; j < redirects.length; j++) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
838 |
equal(redirects[i].equals(redirects[j]), (i == j)); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
839 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
840 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
841 |
// Check basic properties of different types of Redirect |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
842 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
843 |
equal(PIPE.type(), Redirect.Type.PIPE); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
844 |
equal(PIPE.toString(), "PIPE"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
845 |
equal(PIPE.file(), null); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
846 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
847 |
equal(INHERIT.type(), Redirect.Type.INHERIT); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
848 |
equal(INHERIT.toString(), "INHERIT"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
849 |
equal(INHERIT.file(), null); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
850 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
851 |
equal(Redirect.from(ifile).type(), Redirect.Type.READ); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
852 |
equal(Redirect.from(ifile).toString(), |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
853 |
"redirect to read from file \"ifile\""); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
854 |
equal(Redirect.from(ifile).file(), ifile); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
855 |
equal(Redirect.from(ifile), |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
856 |
Redirect.from(ifile)); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
857 |
equal(Redirect.from(ifile).hashCode(), |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
858 |
Redirect.from(ifile).hashCode()); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
859 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
860 |
equal(Redirect.to(ofile).type(), Redirect.Type.WRITE); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
861 |
equal(Redirect.to(ofile).toString(), |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
862 |
"redirect to write to file \"ofile\""); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
863 |
equal(Redirect.to(ofile).file(), ofile); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
864 |
equal(Redirect.to(ofile), |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
865 |
Redirect.to(ofile)); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
866 |
equal(Redirect.to(ofile).hashCode(), |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
867 |
Redirect.to(ofile).hashCode()); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
868 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
869 |
equal(Redirect.appendTo(ofile).type(), Redirect.Type.APPEND); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
870 |
equal(Redirect.appendTo(efile).toString(), |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
871 |
"redirect to append to file \"efile\""); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
872 |
equal(Redirect.appendTo(efile).file(), efile); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
873 |
equal(Redirect.appendTo(efile), |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
874 |
Redirect.appendTo(efile)); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
875 |
equal(Redirect.appendTo(efile).hashCode(), |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
876 |
Redirect.appendTo(efile).hashCode()); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
877 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
878 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
879 |
// Check initial values of redirects |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
880 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
881 |
List<String> childArgs = new ArrayList<String>(javaChildArgs); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
882 |
childArgs.add("testIO"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
883 |
final ProcessBuilder pb = new ProcessBuilder(childArgs); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
884 |
checkRedirects(pb, PIPE, PIPE, PIPE); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
885 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
886 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
887 |
// Check inheritIO |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
888 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
889 |
pb.inheritIO(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
890 |
checkRedirects(pb, INHERIT, INHERIT, INHERIT); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
891 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
892 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
893 |
// Check setters and getters agree |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
894 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
895 |
pb.redirectInput(ifile); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
896 |
equal(pb.redirectInput().file(), ifile); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
897 |
equal(pb.redirectInput(), Redirect.from(ifile)); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
898 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
899 |
pb.redirectOutput(ofile); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
900 |
equal(pb.redirectOutput().file(), ofile); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
901 |
equal(pb.redirectOutput(), Redirect.to(ofile)); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
902 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
903 |
pb.redirectError(efile); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
904 |
equal(pb.redirectError().file(), efile); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
905 |
equal(pb.redirectError(), Redirect.to(efile)); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
906 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
907 |
THROWS(IllegalArgumentException.class, |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
908 |
new Fun(){void f() { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
909 |
pb.redirectInput(Redirect.to(ofile)); }}, |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
910 |
new Fun(){void f() { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
911 |
pb.redirectInput(Redirect.appendTo(ofile)); }}, |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
912 |
new Fun(){void f() { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
913 |
pb.redirectOutput(Redirect.from(ifile)); }}, |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
914 |
new Fun(){void f() { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
915 |
pb.redirectError(Redirect.from(ifile)); }}); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
916 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
917 |
THROWS(IOException.class, |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
918 |
// Input file does not exist |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
919 |
new Fun(){void f() throws Throwable { pb.start(); }}); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
920 |
setFileContents(ifile, "standard input"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
921 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
922 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
923 |
// Writing to non-existent files |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
924 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
925 |
{ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
926 |
ProcessResults r = run(pb); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
927 |
equal(r.exitValue(), 0); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
928 |
equal(fileContents(ofile), "standard output"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
929 |
equal(fileContents(efile), "standard error"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
930 |
equal(r.out(), ""); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
931 |
equal(r.err(), ""); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
932 |
ofile.delete(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
933 |
efile.delete(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
934 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
935 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
936 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
937 |
// Both redirectErrorStream + redirectError |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
938 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
939 |
{ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
940 |
pb.redirectErrorStream(true); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
941 |
ProcessResults r = run(pb); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
942 |
equal(r.exitValue(), 0); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
943 |
equal(fileContents(ofile), |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
944 |
"standard error" + "standard output"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
945 |
equal(fileContents(efile), ""); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
946 |
equal(r.out(), ""); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
947 |
equal(r.err(), ""); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
948 |
ofile.delete(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
949 |
efile.delete(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
950 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
951 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
952 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
953 |
// Appending to existing files |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
954 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
955 |
{ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
956 |
setFileContents(ofile, "ofile-contents"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
957 |
setFileContents(efile, "efile-contents"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
958 |
pb.redirectOutput(Redirect.appendTo(ofile)); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
959 |
pb.redirectError(Redirect.appendTo(efile)); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
960 |
pb.redirectErrorStream(false); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
961 |
ProcessResults r = run(pb); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
962 |
equal(r.exitValue(), 0); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
963 |
equal(fileContents(ofile), |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
964 |
"ofile-contents" + "standard output"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
965 |
equal(fileContents(efile), |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
966 |
"efile-contents" + "standard error"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
967 |
equal(r.out(), ""); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
968 |
equal(r.err(), ""); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
969 |
ofile.delete(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
970 |
efile.delete(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
971 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
972 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
973 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
974 |
// Replacing existing files |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
975 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
976 |
{ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
977 |
setFileContents(ofile, "ofile-contents"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
978 |
setFileContents(efile, "efile-contents"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
979 |
pb.redirectOutput(ofile); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
980 |
pb.redirectError(Redirect.to(efile)); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
981 |
ProcessResults r = run(pb); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
982 |
equal(r.exitValue(), 0); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
983 |
equal(fileContents(ofile), "standard output"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
984 |
equal(fileContents(efile), "standard error"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
985 |
equal(r.out(), ""); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
986 |
equal(r.err(), ""); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
987 |
ofile.delete(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
988 |
efile.delete(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
989 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
990 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
991 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
992 |
// Appending twice to the same file? |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
993 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
994 |
{ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
995 |
setFileContents(ofile, "ofile-contents"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
996 |
setFileContents(efile, "efile-contents"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
997 |
Redirect appender = Redirect.appendTo(ofile); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
998 |
pb.redirectOutput(appender); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
999 |
pb.redirectError(appender); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1000 |
ProcessResults r = run(pb); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1001 |
equal(r.exitValue(), 0); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1002 |
equal(fileContents(ofile), |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1003 |
"ofile-contents" + |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1004 |
"standard error" + |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1005 |
"standard output"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1006 |
equal(fileContents(efile), "efile-contents"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1007 |
equal(r.out(), ""); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1008 |
equal(r.err(), ""); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1009 |
ifile.delete(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1010 |
ofile.delete(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1011 |
efile.delete(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1012 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1013 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1014 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1015 |
// Testing INHERIT is harder. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1016 |
// Note that this requires __FOUR__ nested JVMs involved in one test, |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1017 |
// if you count the harness JVM. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1018 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1019 |
{ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1020 |
redirectIO(pb, PIPE, PIPE, PIPE); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1021 |
List<String> command = pb.command(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1022 |
command.set(command.size() - 1, "testInheritIO"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1023 |
Process p = pb.start(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1024 |
new PrintStream(p.getOutputStream()).print("standard input"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1025 |
p.getOutputStream().close(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1026 |
ProcessResults r = run(p); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1027 |
equal(r.exitValue(), 0); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1028 |
equal(r.out(), "standard output"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1029 |
equal(r.err(), "standard error"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1030 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1031 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1032 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1033 |
// Test security implications of I/O redirection |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1034 |
//---------------------------------------------------------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1035 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1036 |
// Read access to current directory is always granted; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1037 |
// So create a tmpfile for input instead. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1038 |
final File tmpFile = File.createTempFile("Basic", "tmp"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1039 |
setFileContents(tmpFile, "standard input"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1040 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1041 |
final Policy policy = new Policy(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1042 |
Policy.setPolicy(policy); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1043 |
System.setSecurityManager(new SecurityManager()); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1044 |
try { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1045 |
final Permission xPermission |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1046 |
= new FilePermission("<<ALL FILES>>", "execute"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1047 |
final Permission rxPermission |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1048 |
= new FilePermission("<<ALL FILES>>", "read,execute"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1049 |
final Permission wxPermission |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1050 |
= new FilePermission("<<ALL FILES>>", "write,execute"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1051 |
final Permission rwxPermission |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1052 |
= new FilePermission("<<ALL FILES>>", "read,write,execute"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1053 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1054 |
THROWS(SecurityException.class, |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1055 |
new Fun() { void f() throws IOException { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1056 |
policy.setPermissions(xPermission); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1057 |
redirectIO(pb, from(tmpFile), PIPE, PIPE); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1058 |
pb.start();}}, |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1059 |
new Fun() { void f() throws IOException { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1060 |
policy.setPermissions(rxPermission); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1061 |
redirectIO(pb, PIPE, to(ofile), PIPE); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1062 |
pb.start();}}, |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1063 |
new Fun() { void f() throws IOException { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1064 |
policy.setPermissions(rxPermission); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1065 |
redirectIO(pb, PIPE, PIPE, to(efile)); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1066 |
pb.start();}}); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1067 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1068 |
{ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1069 |
policy.setPermissions(rxPermission); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1070 |
redirectIO(pb, from(tmpFile), PIPE, PIPE); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1071 |
ProcessResults r = run(pb); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1072 |
equal(r.out(), "standard output"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1073 |
equal(r.err(), "standard error"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1074 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1075 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1076 |
{ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1077 |
policy.setPermissions(wxPermission); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1078 |
redirectIO(pb, PIPE, to(ofile), to(efile)); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1079 |
Process p = pb.start(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1080 |
new PrintStream(p.getOutputStream()).print("standard input"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1081 |
p.getOutputStream().close(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1082 |
ProcessResults r = run(p); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1083 |
policy.setPermissions(rwxPermission); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1084 |
equal(fileContents(ofile), "standard output"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1085 |
equal(fileContents(efile), "standard error"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1086 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1087 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1088 |
{ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1089 |
policy.setPermissions(rwxPermission); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1090 |
redirectIO(pb, from(tmpFile), to(ofile), to(efile)); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1091 |
ProcessResults r = run(pb); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1092 |
policy.setPermissions(rwxPermission); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1093 |
equal(fileContents(ofile), "standard output"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1094 |
equal(fileContents(efile), "standard error"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1095 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1096 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1097 |
} finally { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1098 |
policy.setPermissions(new RuntimePermission("setSecurityManager")); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1099 |
System.setSecurityManager(null); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1100 |
tmpFile.delete(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1101 |
ifile.delete(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1102 |
ofile.delete(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1103 |
efile.delete(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1104 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1105 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1106 |
|
2 | 1107 |
private static void realMain(String[] args) throws Throwable { |
1108 |
if (Windows.is()) |
|
1109 |
System.out.println("This appears to be a Windows system."); |
|
1110 |
if (Unix.is()) |
|
1111 |
System.out.println("This appears to be a Unix system."); |
|
1112 |
if (UnicodeOS.is()) |
|
1113 |
System.out.println("This appears to be a Unicode-based OS."); |
|
1114 |
||
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1115 |
try { testIORedirection(); } |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1116 |
catch (Throwable t) { unexpected(t); } |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1117 |
|
2 | 1118 |
//---------------------------------------------------------------- |
1119 |
// Basic tests for setting, replacing and deleting envvars |
|
1120 |
//---------------------------------------------------------------- |
|
1121 |
try { |
|
1122 |
ProcessBuilder pb = new ProcessBuilder(); |
|
1123 |
Map<String,String> environ = pb.environment(); |
|
1124 |
||
1125 |
// New env var |
|
1126 |
environ.put("QUUX", "BAR"); |
|
1127 |
equal(environ.get("QUUX"), "BAR"); |
|
1128 |
equal(getenvInChild(pb,"QUUX"), "BAR"); |
|
1129 |
||
1130 |
// Modify env var |
|
1131 |
environ.put("QUUX","bear"); |
|
1132 |
equal(environ.get("QUUX"), "bear"); |
|
1133 |
equal(getenvInChild(pb,"QUUX"), "bear"); |
|
1134 |
checkMapSanity(environ); |
|
1135 |
||
1136 |
// Remove env var |
|
1137 |
environ.remove("QUUX"); |
|
1138 |
equal(environ.get("QUUX"), null); |
|
1139 |
equal(getenvInChild(pb,"QUUX"), "null"); |
|
1140 |
checkMapSanity(environ); |
|
1141 |
||
1142 |
// Remove non-existent env var |
|
1143 |
environ.remove("QUUX"); |
|
1144 |
equal(environ.get("QUUX"), null); |
|
1145 |
equal(getenvInChild(pb,"QUUX"), "null"); |
|
1146 |
checkMapSanity(environ); |
|
1147 |
} catch (Throwable t) { unexpected(t); } |
|
1148 |
||
1149 |
//---------------------------------------------------------------- |
|
1150 |
// Pass Empty environment to child |
|
1151 |
//---------------------------------------------------------------- |
|
1152 |
try { |
|
1153 |
ProcessBuilder pb = new ProcessBuilder(); |
|
1154 |
pb.environment().clear(); |
|
8561
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
1155 |
String expected = Windows.is() ? "SystemRoot="+systemRoot+",": ""; |
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
1156 |
if (Windows.is()) { |
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
1157 |
pb.environment().put("SystemRoot", systemRoot); |
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
1158 |
} |
12047
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1159 |
String result = getenvInChild(pb); |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1160 |
if (MacOSX.is()) { |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1161 |
result = removeMacExpectedVars(result); |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1162 |
} |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1163 |
equal(result, expected); |
2 | 1164 |
} catch (Throwable t) { unexpected(t); } |
1165 |
||
1166 |
//---------------------------------------------------------------- |
|
1167 |
// System.getenv() is read-only. |
|
1168 |
//---------------------------------------------------------------- |
|
1169 |
THROWS(UnsupportedOperationException.class, |
|
1170 |
new Fun(){void f(){ getenv().put("FOO","BAR");}}, |
|
1171 |
new Fun(){void f(){ getenv().remove("PATH");}}, |
|
1172 |
new Fun(){void f(){ getenv().keySet().remove("PATH");}}, |
|
1173 |
new Fun(){void f(){ getenv().values().remove("someValue");}}); |
|
1174 |
||
1175 |
try { |
|
1176 |
Collection<Map.Entry<String,String>> c = getenv().entrySet(); |
|
1177 |
if (! c.isEmpty()) |
|
1178 |
try { |
|
1179 |
c.iterator().next().setValue("foo"); |
|
1180 |
fail("Expected UnsupportedOperationException not thrown"); |
|
1181 |
} catch (UnsupportedOperationException e) {} // OK |
|
1182 |
} catch (Throwable t) { unexpected(t); } |
|
1183 |
||
1184 |
//---------------------------------------------------------------- |
|
1185 |
// System.getenv() always returns the same object in our implementation. |
|
1186 |
//---------------------------------------------------------------- |
|
1187 |
try { |
|
1188 |
check(System.getenv() == System.getenv()); |
|
1189 |
} catch (Throwable t) { unexpected(t); } |
|
1190 |
||
1191 |
//---------------------------------------------------------------- |
|
1192 |
// You can't create an env var name containing "=", |
|
1193 |
// or an env var name or value containing NUL. |
|
1194 |
//---------------------------------------------------------------- |
|
1195 |
{ |
|
1196 |
final Map<String,String> m = new ProcessBuilder().environment(); |
|
1197 |
THROWS(IllegalArgumentException.class, |
|
1198 |
new Fun(){void f(){ m.put("FOO=","BAR");}}, |
|
1199 |
new Fun(){void f(){ m.put("FOO\u0000","BAR");}}, |
|
1200 |
new Fun(){void f(){ m.put("FOO","BAR\u0000");}}); |
|
1201 |
} |
|
1202 |
||
1203 |
//---------------------------------------------------------------- |
|
1204 |
// Commands must never be null. |
|
1205 |
//---------------------------------------------------------------- |
|
1206 |
THROWS(NullPointerException.class, |
|
1207 |
new Fun(){void f(){ |
|
1208 |
new ProcessBuilder((List<String>)null);}}, |
|
1209 |
new Fun(){void f(){ |
|
1210 |
new ProcessBuilder().command((List<String>)null);}}); |
|
1211 |
||
1212 |
//---------------------------------------------------------------- |
|
1213 |
// Put in a command; get the same one back out. |
|
1214 |
//---------------------------------------------------------------- |
|
1215 |
try { |
|
1216 |
List<String> command = new ArrayList<String>(); |
|
1217 |
ProcessBuilder pb = new ProcessBuilder(command); |
|
1218 |
check(pb.command() == command); |
|
1219 |
List<String> command2 = new ArrayList<String>(2); |
|
1220 |
command2.add("foo"); |
|
1221 |
command2.add("bar"); |
|
1222 |
pb.command(command2); |
|
1223 |
check(pb.command() == command2); |
|
1224 |
pb.command("foo", "bar"); |
|
1225 |
check(pb.command() != command2 && pb.command().equals(command2)); |
|
1226 |
pb.command(command2); |
|
1227 |
command2.add("baz"); |
|
1228 |
equal(pb.command().get(2), "baz"); |
|
1229 |
} catch (Throwable t) { unexpected(t); } |
|
1230 |
||
1231 |
//---------------------------------------------------------------- |
|
1232 |
// Commands must contain at least one element. |
|
1233 |
//---------------------------------------------------------------- |
|
1234 |
THROWS(IndexOutOfBoundsException.class, |
|
1235 |
new Fun() { void f() throws IOException { |
|
1236 |
new ProcessBuilder().start();}}, |
|
1237 |
new Fun() { void f() throws IOException { |
|
1238 |
new ProcessBuilder(new ArrayList<String>()).start();}}, |
|
1239 |
new Fun() { void f() throws IOException { |
|
1240 |
Runtime.getRuntime().exec(new String[]{});}}); |
|
1241 |
||
1242 |
//---------------------------------------------------------------- |
|
1243 |
// Commands must not contain null elements at start() time. |
|
1244 |
//---------------------------------------------------------------- |
|
1245 |
THROWS(NullPointerException.class, |
|
1246 |
new Fun() { void f() throws IOException { |
|
1247 |
new ProcessBuilder("foo",null,"bar").start();}}, |
|
1248 |
new Fun() { void f() throws IOException { |
|
1249 |
new ProcessBuilder((String)null).start();}}, |
|
1250 |
new Fun() { void f() throws IOException { |
|
1251 |
new ProcessBuilder(new String[]{null}).start();}}, |
|
1252 |
new Fun() { void f() throws IOException { |
|
1253 |
new ProcessBuilder(new String[]{"foo",null,"bar"}).start();}}); |
|
1254 |
||
1255 |
//---------------------------------------------------------------- |
|
1256 |
// Command lists are growable. |
|
1257 |
//---------------------------------------------------------------- |
|
1258 |
try { |
|
1259 |
new ProcessBuilder().command().add("foo"); |
|
1260 |
new ProcessBuilder("bar").command().add("foo"); |
|
1261 |
new ProcessBuilder(new String[]{"1","2"}).command().add("3"); |
|
1262 |
} catch (Throwable t) { unexpected(t); } |
|
1263 |
||
1264 |
//---------------------------------------------------------------- |
|
1265 |
// Nulls in environment updates generate NullPointerException |
|
1266 |
//---------------------------------------------------------------- |
|
1267 |
try { |
|
1268 |
final Map<String,String> env = new ProcessBuilder().environment(); |
|
1269 |
THROWS(NullPointerException.class, |
|
1270 |
new Fun(){void f(){ env.put("foo",null);}}, |
|
1271 |
new Fun(){void f(){ env.put(null,"foo");}}, |
|
1272 |
new Fun(){void f(){ env.remove(null);}}, |
|
1273 |
new Fun(){void f(){ |
|
1274 |
for (Map.Entry<String,String> e : env.entrySet()) |
|
1275 |
e.setValue(null);}}, |
|
1276 |
new Fun() { void f() throws IOException { |
|
1277 |
Runtime.getRuntime().exec(new String[]{"foo"}, |
|
1278 |
new String[]{null});}}); |
|
1279 |
} catch (Throwable t) { unexpected(t); } |
|
1280 |
||
1281 |
//---------------------------------------------------------------- |
|
1282 |
// Non-String types in environment updates generate ClassCastException |
|
1283 |
//---------------------------------------------------------------- |
|
1284 |
try { |
|
1285 |
final Map<String,String> env = new ProcessBuilder().environment(); |
|
1286 |
THROWS(ClassCastException.class, |
|
1287 |
new Fun(){void f(){ env.remove(TRUE);}}, |
|
1288 |
new Fun(){void f(){ env.keySet().remove(TRUE);}}, |
|
1289 |
new Fun(){void f(){ env.values().remove(TRUE);}}, |
|
1290 |
new Fun(){void f(){ env.entrySet().remove(TRUE);}}); |
|
1291 |
} catch (Throwable t) { unexpected(t); } |
|
1292 |
||
1293 |
//---------------------------------------------------------------- |
|
1294 |
// Check query operations on environment maps |
|
1295 |
//---------------------------------------------------------------- |
|
1296 |
try { |
|
1297 |
List<Map<String,String>> envs = |
|
1298 |
new ArrayList<Map<String,String>>(2); |
|
1299 |
envs.add(System.getenv()); |
|
1300 |
envs.add(new ProcessBuilder().environment()); |
|
1301 |
for (final Map<String,String> env : envs) { |
|
1302 |
//---------------------------------------------------------------- |
|
1303 |
// Nulls in environment queries are forbidden. |
|
1304 |
//---------------------------------------------------------------- |
|
1305 |
THROWS(NullPointerException.class, |
|
1306 |
new Fun(){void f(){ getenv(null);}}, |
|
1307 |
new Fun(){void f(){ env.get(null);}}, |
|
1308 |
new Fun(){void f(){ env.containsKey(null);}}, |
|
1309 |
new Fun(){void f(){ env.containsValue(null);}}, |
|
1310 |
new Fun(){void f(){ env.keySet().contains(null);}}, |
|
1311 |
new Fun(){void f(){ env.values().contains(null);}}); |
|
1312 |
||
1313 |
//---------------------------------------------------------------- |
|
1314 |
// Non-String types in environment queries are forbidden. |
|
1315 |
//---------------------------------------------------------------- |
|
1316 |
THROWS(ClassCastException.class, |
|
1317 |
new Fun(){void f(){ env.get(TRUE);}}, |
|
1318 |
new Fun(){void f(){ env.containsKey(TRUE);}}, |
|
1319 |
new Fun(){void f(){ env.containsValue(TRUE);}}, |
|
1320 |
new Fun(){void f(){ env.keySet().contains(TRUE);}}, |
|
1321 |
new Fun(){void f(){ env.values().contains(TRUE);}}); |
|
1322 |
||
1323 |
//---------------------------------------------------------------- |
|
1324 |
// Illegal String values in environment queries are (grumble) OK |
|
1325 |
//---------------------------------------------------------------- |
|
1326 |
equal(env.get("\u0000"), null); |
|
1327 |
check(! env.containsKey("\u0000")); |
|
1328 |
check(! env.containsValue("\u0000")); |
|
1329 |
check(! env.keySet().contains("\u0000")); |
|
1330 |
check(! env.values().contains("\u0000")); |
|
1331 |
} |
|
1332 |
||
1333 |
} catch (Throwable t) { unexpected(t); } |
|
1334 |
||
1335 |
try { |
|
1336 |
final Set<Map.Entry<String,String>> entrySet = |
|
1337 |
new ProcessBuilder().environment().entrySet(); |
|
1338 |
THROWS(NullPointerException.class, |
|
1339 |
new Fun(){void f(){ entrySet.contains(null);}}); |
|
1340 |
THROWS(ClassCastException.class, |
|
1341 |
new Fun(){void f(){ entrySet.contains(TRUE);}}, |
|
1342 |
new Fun(){void f(){ |
|
1343 |
entrySet.contains( |
|
1344 |
new SimpleImmutableEntry<Boolean,String>(TRUE,""));}}); |
|
1345 |
||
1346 |
check(! entrySet.contains |
|
1347 |
(new SimpleImmutableEntry<String,String>("", ""))); |
|
1348 |
} catch (Throwable t) { unexpected(t); } |
|
1349 |
||
1350 |
//---------------------------------------------------------------- |
|
1351 |
// Put in a directory; get the same one back out. |
|
1352 |
//---------------------------------------------------------------- |
|
1353 |
try { |
|
1354 |
ProcessBuilder pb = new ProcessBuilder(); |
|
1355 |
File foo = new File("foo"); |
|
1356 |
equal(pb.directory(), null); |
|
1357 |
equal(pb.directory(foo).directory(), foo); |
|
1358 |
equal(pb.directory(null).directory(), null); |
|
1359 |
} catch (Throwable t) { unexpected(t); } |
|
1360 |
||
1361 |
//---------------------------------------------------------------- |
|
1362 |
// If round-trip conversion works, check envvar pass-through to child |
|
1363 |
//---------------------------------------------------------------- |
|
1364 |
try { |
|
1365 |
testEncoding("ASCII", "xyzzy"); |
|
1366 |
testEncoding("Latin1", "\u00f1\u00e1"); |
|
1367 |
testEncoding("Unicode", "\u22f1\u11e1"); |
|
1368 |
} catch (Throwable t) { unexpected(t); } |
|
1369 |
||
1370 |
//---------------------------------------------------------------- |
|
1371 |
// A surprisingly large number of ways to delete an environment var. |
|
1372 |
//---------------------------------------------------------------- |
|
1373 |
testVariableDeleter(new EnvironmentFrobber() { |
|
1374 |
public void doIt(Map<String,String> environ) { |
|
1375 |
environ.remove("Foo");}}); |
|
1376 |
||
1377 |
testVariableDeleter(new EnvironmentFrobber() { |
|
1378 |
public void doIt(Map<String,String> environ) { |
|
1379 |
environ.keySet().remove("Foo");}}); |
|
1380 |
||
1381 |
testVariableDeleter(new EnvironmentFrobber() { |
|
1382 |
public void doIt(Map<String,String> environ) { |
|
1383 |
environ.values().remove("BAAR");}}); |
|
1384 |
||
1385 |
testVariableDeleter(new EnvironmentFrobber() { |
|
1386 |
public void doIt(Map<String,String> environ) { |
|
1387 |
// Legally fabricate a ProcessEnvironment.StringEntry, |
|
1388 |
// even though it's private. |
|
1389 |
Map<String,String> environ2 |
|
1390 |
= new ProcessBuilder().environment(); |
|
1391 |
environ2.clear(); |
|
1392 |
environ2.put("Foo","BAAR"); |
|
1393 |
// Subtlety alert. |
|
1394 |
Map.Entry<String,String> e |
|
1395 |
= environ2.entrySet().iterator().next(); |
|
1396 |
environ.entrySet().remove(e);}}); |
|
1397 |
||
1398 |
testVariableDeleter(new EnvironmentFrobber() { |
|
1399 |
public void doIt(Map<String,String> environ) { |
|
1400 |
Map.Entry<String,String> victim = null; |
|
1401 |
for (Map.Entry<String,String> e : environ.entrySet()) |
|
1402 |
if (e.getKey().equals("Foo")) |
|
1403 |
victim = e; |
|
1404 |
if (victim != null) |
|
1405 |
environ.entrySet().remove(victim);}}); |
|
1406 |
||
1407 |
testVariableDeleter(new EnvironmentFrobber() { |
|
1408 |
public void doIt(Map<String,String> environ) { |
|
1409 |
Iterator<String> it = environ.keySet().iterator(); |
|
1410 |
while (it.hasNext()) { |
|
1411 |
String val = it.next(); |
|
1412 |
if (val.equals("Foo")) |
|
1413 |
it.remove();}}}); |
|
1414 |
||
1415 |
testVariableDeleter(new EnvironmentFrobber() { |
|
1416 |
public void doIt(Map<String,String> environ) { |
|
1417 |
Iterator<Map.Entry<String,String>> it |
|
1418 |
= environ.entrySet().iterator(); |
|
1419 |
while (it.hasNext()) { |
|
1420 |
Map.Entry<String,String> e = it.next(); |
|
1421 |
if (e.getKey().equals("Foo")) |
|
1422 |
it.remove();}}}); |
|
1423 |
||
1424 |
testVariableDeleter(new EnvironmentFrobber() { |
|
1425 |
public void doIt(Map<String,String> environ) { |
|
1426 |
Iterator<String> it = environ.values().iterator(); |
|
1427 |
while (it.hasNext()) { |
|
1428 |
String val = it.next(); |
|
1429 |
if (val.equals("BAAR")) |
|
1430 |
it.remove();}}}); |
|
1431 |
||
1432 |
//---------------------------------------------------------------- |
|
1433 |
// A surprisingly small number of ways to add an environment var. |
|
1434 |
//---------------------------------------------------------------- |
|
1435 |
testVariableAdder(new EnvironmentFrobber() { |
|
1436 |
public void doIt(Map<String,String> environ) { |
|
1437 |
environ.put("Foo","Bahrein");}}); |
|
1438 |
||
1439 |
//---------------------------------------------------------------- |
|
1440 |
// A few ways to modify an environment var. |
|
1441 |
//---------------------------------------------------------------- |
|
1442 |
testVariableModifier(new EnvironmentFrobber() { |
|
1443 |
public void doIt(Map<String,String> environ) { |
|
1444 |
environ.put("Foo","NewValue");}}); |
|
1445 |
||
1446 |
testVariableModifier(new EnvironmentFrobber() { |
|
1447 |
public void doIt(Map<String,String> environ) { |
|
1448 |
for (Map.Entry<String,String> e : environ.entrySet()) |
|
1449 |
if (e.getKey().equals("Foo")) |
|
1450 |
e.setValue("NewValue");}}); |
|
1451 |
||
1452 |
//---------------------------------------------------------------- |
|
1453 |
// Fiddle with environment sizes |
|
1454 |
//---------------------------------------------------------------- |
|
1455 |
try { |
|
1456 |
Map<String,String> environ = new ProcessBuilder().environment(); |
|
1457 |
int size = environ.size(); |
|
1458 |
checkSizes(environ, size); |
|
1459 |
||
1460 |
environ.put("UnLiKeLYeNVIROmtNam", "someVal"); |
|
1461 |
checkSizes(environ, size+1); |
|
1462 |
||
1463 |
// Check for environment independence |
|
1464 |
new ProcessBuilder().environment().clear(); |
|
1465 |
||
1466 |
environ.put("UnLiKeLYeNVIROmtNam", "someOtherVal"); |
|
1467 |
checkSizes(environ, size+1); |
|
1468 |
||
1469 |
environ.remove("UnLiKeLYeNVIROmtNam"); |
|
1470 |
checkSizes(environ, size); |
|
1471 |
||
1472 |
environ.clear(); |
|
1473 |
checkSizes(environ, 0); |
|
1474 |
||
1475 |
environ.clear(); |
|
1476 |
checkSizes(environ, 0); |
|
1477 |
||
1478 |
environ = new ProcessBuilder().environment(); |
|
1479 |
environ.keySet().clear(); |
|
1480 |
checkSizes(environ, 0); |
|
1481 |
||
1482 |
environ = new ProcessBuilder().environment(); |
|
1483 |
environ.entrySet().clear(); |
|
1484 |
checkSizes(environ, 0); |
|
1485 |
||
1486 |
environ = new ProcessBuilder().environment(); |
|
1487 |
environ.values().clear(); |
|
1488 |
checkSizes(environ, 0); |
|
1489 |
} catch (Throwable t) { unexpected(t); } |
|
1490 |
||
1491 |
//---------------------------------------------------------------- |
|
1492 |
// Check that various map invariants hold |
|
1493 |
//---------------------------------------------------------------- |
|
1494 |
checkMapSanity(new ProcessBuilder().environment()); |
|
1495 |
checkMapSanity(System.getenv()); |
|
1496 |
checkMapEquality(new ProcessBuilder().environment(), |
|
1497 |
new ProcessBuilder().environment()); |
|
1498 |
||
1499 |
||
1500 |
//---------------------------------------------------------------- |
|
1501 |
// Check effects on external "env" command. |
|
1502 |
//---------------------------------------------------------------- |
|
1503 |
try { |
|
1504 |
Set<String> env1 = new HashSet<String> |
|
1505 |
(Arrays.asList(nativeEnv((String[])null).split("\n"))); |
|
1506 |
||
1507 |
ProcessBuilder pb = new ProcessBuilder(); |
|
1508 |
pb.environment().put("QwErTyUiOp","AsDfGhJk"); |
|
1509 |
||
1510 |
Set<String> env2 = new HashSet<String> |
|
1511 |
(Arrays.asList(nativeEnv(pb).split("\n"))); |
|
1512 |
||
1513 |
check(env2.size() == env1.size() + 1); |
|
1514 |
env1.add("QwErTyUiOp=AsDfGhJk"); |
|
1515 |
check(env1.equals(env2)); |
|
1516 |
} catch (Throwable t) { unexpected(t); } |
|
1517 |
||
1518 |
//---------------------------------------------------------------- |
|
1519 |
// Test Runtime.exec(...envp...) |
|
1520 |
// Check for sort order of environment variables on Windows. |
|
1521 |
//---------------------------------------------------------------- |
|
1522 |
try { |
|
9500
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
9035
diff
changeset
|
1523 |
String systemRoot = "SystemRoot=" + System.getenv("SystemRoot"); |
2 | 1524 |
// '+' < 'A' < 'Z' < '_' < 'a' < 'z' < '~' |
1525 |
String[]envp = {"FOO=BAR","BAZ=GORP","QUUX=", |
|
9500
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
9035
diff
changeset
|
1526 |
"+=+", "_=_", "~=~", systemRoot}; |
2 | 1527 |
String output = nativeEnv(envp); |
9500
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
9035
diff
changeset
|
1528 |
String expected = "+=+\nBAZ=GORP\nFOO=BAR\nQUUX=\n"+systemRoot+"\n_=_\n~=~\n"; |
2 | 1529 |
// On Windows, Java must keep the environment sorted. |
1530 |
// Order is random on Unix, so this test does the sort. |
|
1531 |
if (! Windows.is()) |
|
1532 |
output = sortByLinesWindowsly(output); |
|
1533 |
equal(output, expected); |
|
1534 |
} catch (Throwable t) { unexpected(t); } |
|
1535 |
||
1536 |
//---------------------------------------------------------------- |
|
9500
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
9035
diff
changeset
|
1537 |
// Test Runtime.exec(...envp...) |
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
9035
diff
changeset
|
1538 |
// and check SystemRoot gets set automatically on Windows |
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
9035
diff
changeset
|
1539 |
//---------------------------------------------------------------- |
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
9035
diff
changeset
|
1540 |
try { |
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
9035
diff
changeset
|
1541 |
if (Windows.is()) { |
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
9035
diff
changeset
|
1542 |
String systemRoot = "SystemRoot=" + System.getenv("SystemRoot"); |
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
9035
diff
changeset
|
1543 |
String[]envp = {"FOO=BAR","BAZ=GORP","QUUX=", |
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
9035
diff
changeset
|
1544 |
"+=+", "_=_", "~=~"}; |
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
9035
diff
changeset
|
1545 |
String output = nativeEnv(envp); |
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
9035
diff
changeset
|
1546 |
String expected = "+=+\nBAZ=GORP\nFOO=BAR\nQUUX=\n"+systemRoot+"\n_=_\n~=~\n"; |
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
9035
diff
changeset
|
1547 |
equal(output, expected); |
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
9035
diff
changeset
|
1548 |
} |
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
9035
diff
changeset
|
1549 |
} catch (Throwable t) { unexpected(t); } |
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
9035
diff
changeset
|
1550 |
|
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
9035
diff
changeset
|
1551 |
//---------------------------------------------------------------- |
2 | 1552 |
// System.getenv() must be consistent with System.getenv(String) |
1553 |
//---------------------------------------------------------------- |
|
1554 |
try { |
|
1555 |
for (Map.Entry<String,String> e : getenv().entrySet()) |
|
1556 |
equal(getenv(e.getKey()), e.getValue()); |
|
1557 |
} catch (Throwable t) { unexpected(t); } |
|
1558 |
||
1559 |
//---------------------------------------------------------------- |
|
1560 |
// Fiddle with working directory in child |
|
1561 |
//---------------------------------------------------------------- |
|
1562 |
try { |
|
1563 |
String canonicalUserDir = |
|
1564 |
new File(System.getProperty("user.dir")).getCanonicalPath(); |
|
1565 |
String[] sdirs = new String[] |
|
1566 |
{".", "..", "/", "/bin", |
|
5168
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1567 |
"C:", "c:", "C:/", "c:\\", "\\", "\\bin", |
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1568 |
"c:\\windows ", "c:\\Program Files", "c:\\Program Files\\" }; |
2 | 1569 |
for (String sdir : sdirs) { |
1570 |
File dir = new File(sdir); |
|
1571 |
if (! (dir.isDirectory() && dir.exists())) |
|
1572 |
continue; |
|
1573 |
out.println("Testing directory " + dir); |
|
5168
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1574 |
//dir = new File(dir.getCanonicalPath()); |
2 | 1575 |
|
1576 |
ProcessBuilder pb = new ProcessBuilder(); |
|
1577 |
equal(pb.directory(), null); |
|
1578 |
equal(pwdInChild(pb), canonicalUserDir); |
|
1579 |
||
1580 |
pb.directory(dir); |
|
1581 |
equal(pb.directory(), dir); |
|
5168
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1582 |
equal(pwdInChild(pb), dir.getCanonicalPath()); |
2 | 1583 |
|
1584 |
pb.directory(null); |
|
1585 |
equal(pb.directory(), null); |
|
1586 |
equal(pwdInChild(pb), canonicalUserDir); |
|
1587 |
||
1588 |
pb.directory(dir); |
|
1589 |
} |
|
1590 |
} catch (Throwable t) { unexpected(t); } |
|
1591 |
||
1592 |
//---------------------------------------------------------------- |
|
5168
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1593 |
// Working directory with Unicode in child |
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1594 |
//---------------------------------------------------------------- |
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1595 |
try { |
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1596 |
if (UnicodeOS.is()) { |
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1597 |
File dir = new File(System.getProperty("test.dir", "."), |
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1598 |
"ProcessBuilderDir\u4e00\u4e02"); |
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1599 |
try { |
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1600 |
if (!dir.exists()) |
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1601 |
dir.mkdir(); |
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1602 |
out.println("Testing Unicode directory:" + dir); |
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1603 |
ProcessBuilder pb = new ProcessBuilder(); |
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1604 |
pb.directory(dir); |
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1605 |
equal(pwdInChild(pb), dir.getCanonicalPath()); |
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1606 |
} finally { |
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1607 |
if (dir.exists()) |
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1608 |
dir.delete(); |
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1609 |
} |
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1610 |
} |
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1611 |
} catch (Throwable t) { unexpected(t); } |
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1612 |
|
41e46b5d9b15
4947220: (process)Runtime.exec() cannot invoke applications with unicode parameters(win)
sherman
parents:
3840
diff
changeset
|
1613 |
//---------------------------------------------------------------- |
3840
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
1614 |
// OOME in child allocating maximally sized array |
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
1615 |
// Test for hotspot/jvmti bug 6850957 |
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
1616 |
//---------------------------------------------------------------- |
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
1617 |
try { |
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
1618 |
List<String> list = new ArrayList<String>(javaChildArgs); |
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
1619 |
list.add(1, String.format("-XX:OnOutOfMemoryError=%s -version", |
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
1620 |
javaExe)); |
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
1621 |
list.add("ArrayOOME"); |
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
1622 |
ProcessResults r = run(new ProcessBuilder(list)); |
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
1623 |
check(r.out().contains("java.lang.OutOfMemoryError:")); |
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
1624 |
check(r.out().contains(javaExe)); |
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
1625 |
check(r.err().contains(System.getProperty("java.version"))); |
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
1626 |
equal(r.exitValue(), 1); |
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
1627 |
} catch (Throwable t) { unexpected(t); } |
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
1628 |
|
37fca95e51fd
6850958: Honor -XX:OnOutOfMemoryError when array size exceeds VM limit
martin
parents:
2946
diff
changeset
|
1629 |
//---------------------------------------------------------------- |
2 | 1630 |
// Windows has tricky semi-case-insensitive semantics |
1631 |
//---------------------------------------------------------------- |
|
1632 |
if (Windows.is()) |
|
1633 |
try { |
|
1634 |
out.println("Running case insensitve variable tests"); |
|
1635 |
for (String[] namePair : |
|
1636 |
new String[][] |
|
1637 |
{ new String[]{"PATH","PaTh"}, |
|
1638 |
new String[]{"home","HOME"}, |
|
1639 |
new String[]{"SYSTEMROOT","SystemRoot"}}) { |
|
1640 |
check((getenv(namePair[0]) == null && |
|
1641 |
getenv(namePair[1]) == null) |
|
1642 |
|| |
|
1643 |
getenv(namePair[0]).equals(getenv(namePair[1])), |
|
1644 |
"Windows environment variables are not case insensitive"); |
|
1645 |
} |
|
1646 |
} catch (Throwable t) { unexpected(t); } |
|
1647 |
||
1648 |
//---------------------------------------------------------------- |
|
1649 |
// Test proper Unicode child environment transfer |
|
1650 |
//---------------------------------------------------------------- |
|
1651 |
if (UnicodeOS.is()) |
|
1652 |
try { |
|
1653 |
ProcessBuilder pb = new ProcessBuilder(); |
|
1654 |
pb.environment().put("\u1234","\u5678"); |
|
1655 |
pb.environment().remove("PATH"); |
|
1656 |
equal(getenvInChild1234(pb), "\u5678"); |
|
1657 |
} catch (Throwable t) { unexpected(t); } |
|
1658 |
||
1659 |
||
1660 |
//---------------------------------------------------------------- |
|
1661 |
// Test Runtime.exec(...envp...) with envstrings with initial `=' |
|
1662 |
//---------------------------------------------------------------- |
|
1663 |
try { |
|
1664 |
List<String> childArgs = new ArrayList<String>(javaChildArgs); |
|
1665 |
childArgs.add("System.getenv()"); |
|
1666 |
String[] cmdp = childArgs.toArray(new String[childArgs.size()]); |
|
8561
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
1667 |
String[] envp; |
12882
35d381df9422
7174723: TEST_BUG: java/lang/ProcessBuilder/Basic.java failing [win]
alanb
parents:
12538
diff
changeset
|
1668 |
String[] envpWin = {"=C:=\\", "=ExitValue=3", "SystemRoot="+systemRoot}; |
8561
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
1669 |
String[] envpOth = {"=ExitValue=3", "=C:=\\"}; |
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
1670 |
if (Windows.is()) { |
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
1671 |
envp = envpWin; |
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
1672 |
} else { |
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
1673 |
envp = envpOth; |
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
1674 |
} |
2 | 1675 |
Process p = Runtime.getRuntime().exec(cmdp, envp); |
12882
35d381df9422
7174723: TEST_BUG: java/lang/ProcessBuilder/Basic.java failing [win]
alanb
parents:
12538
diff
changeset
|
1676 |
String expected = Windows.is() ? "=C:=\\,=ExitValue=3,SystemRoot="+systemRoot+"," : "=C:=\\,"; |
12047
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1677 |
String commandOutput = commandOutput(p); |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1678 |
if (MacOSX.is()) { |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1679 |
commandOutput = removeMacExpectedVars(commandOutput); |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1680 |
} |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1681 |
equal(commandOutput, expected); |
2 | 1682 |
if (Windows.is()) { |
1683 |
ProcessBuilder pb = new ProcessBuilder(childArgs); |
|
1684 |
pb.environment().clear(); |
|
8561
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
1685 |
pb.environment().put("SystemRoot", systemRoot); |
2 | 1686 |
pb.environment().put("=ExitValue", "3"); |
1687 |
pb.environment().put("=C:", "\\"); |
|
1688 |
equal(commandOutput(pb), expected); |
|
1689 |
} |
|
1690 |
} catch (Throwable t) { unexpected(t); } |
|
1691 |
||
1692 |
//---------------------------------------------------------------- |
|
1693 |
// Test Runtime.exec(...envp...) with envstrings without any `=' |
|
1694 |
//---------------------------------------------------------------- |
|
1695 |
try { |
|
1696 |
String[] cmdp = {"echo"}; |
|
1697 |
String[] envp = {"Hello", "World"}; // Yuck! |
|
1698 |
Process p = Runtime.getRuntime().exec(cmdp, envp); |
|
1699 |
equal(commandOutput(p), "\n"); |
|
1700 |
} catch (Throwable t) { unexpected(t); } |
|
1701 |
||
1702 |
//---------------------------------------------------------------- |
|
1703 |
// Test Runtime.exec(...envp...) with envstrings containing NULs |
|
1704 |
//---------------------------------------------------------------- |
|
1705 |
try { |
|
1706 |
List<String> childArgs = new ArrayList<String>(javaChildArgs); |
|
1707 |
childArgs.add("System.getenv()"); |
|
1708 |
String[] cmdp = childArgs.toArray(new String[childArgs.size()]); |
|
8561
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
1709 |
String[] envpWin = {"SystemRoot="+systemRoot, "LC_ALL=C\u0000\u0000", // Yuck! |
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
1710 |
"FO\u0000=B\u0000R"}; |
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
1711 |
String[] envpOth = {"LC_ALL=C\u0000\u0000", // Yuck! |
2 | 1712 |
"FO\u0000=B\u0000R"}; |
8561
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
1713 |
String[] envp; |
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
1714 |
if (Windows.is()) { |
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
1715 |
envp = envpWin; |
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
1716 |
} else { |
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
1717 |
envp = envpOth; |
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
1718 |
} |
12047
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1719 |
System.out.println ("cmdp"); |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1720 |
for (int i=0; i<cmdp.length; i++) { |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1721 |
System.out.printf ("cmdp %d: %s\n", i, cmdp[i]); |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1722 |
} |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1723 |
System.out.println ("envp"); |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1724 |
for (int i=0; i<envp.length; i++) { |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1725 |
System.out.printf ("envp %d: %s\n", i, envp[i]); |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1726 |
} |
2 | 1727 |
Process p = Runtime.getRuntime().exec(cmdp, envp); |
12047
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1728 |
String commandOutput = commandOutput(p); |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1729 |
if (MacOSX.is()) { |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1730 |
commandOutput = removeMacExpectedVars(commandOutput); |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1731 |
} |
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1732 |
check(commandOutput.equals(Windows.is() |
12882
35d381df9422
7174723: TEST_BUG: java/lang/ProcessBuilder/Basic.java failing [win]
alanb
parents:
12538
diff
changeset
|
1733 |
? "LC_ALL=C,SystemRoot="+systemRoot+"," |
12047
320a714614e9
7113349: Initial changeset for Macosx port to jdk
michaelm
parents:
10347
diff
changeset
|
1734 |
: "LC_ALL=C,"), |
2 | 1735 |
"Incorrect handling of envstrings containing NULs"); |
1736 |
} catch (Throwable t) { unexpected(t); } |
|
1737 |
||
1738 |
//---------------------------------------------------------------- |
|
1739 |
// Test the redirectErrorStream property |
|
1740 |
//---------------------------------------------------------------- |
|
1741 |
try { |
|
1742 |
ProcessBuilder pb = new ProcessBuilder(); |
|
1743 |
equal(pb.redirectErrorStream(), false); |
|
1744 |
equal(pb.redirectErrorStream(true), pb); |
|
1745 |
equal(pb.redirectErrorStream(), true); |
|
1746 |
equal(pb.redirectErrorStream(false), pb); |
|
1747 |
equal(pb.redirectErrorStream(), false); |
|
1748 |
} catch (Throwable t) { unexpected(t); } |
|
1749 |
||
1750 |
try { |
|
1751 |
List<String> childArgs = new ArrayList<String>(javaChildArgs); |
|
1752 |
childArgs.add("OutErr"); |
|
1753 |
ProcessBuilder pb = new ProcessBuilder(childArgs); |
|
1754 |
{ |
|
2946
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
1755 |
ProcessResults r = run(pb); |
2 | 1756 |
equal(r.out(), "outout"); |
1757 |
equal(r.err(), "errerr"); |
|
1758 |
} |
|
1759 |
{ |
|
1760 |
pb.redirectErrorStream(true); |
|
2946
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
1761 |
ProcessResults r = run(pb); |
2 | 1762 |
equal(r.out(), "outerrouterr"); |
1763 |
equal(r.err(), ""); |
|
1764 |
} |
|
1765 |
} catch (Throwable t) { unexpected(t); } |
|
1766 |
||
2946
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
1767 |
if (Unix.is()) { |
2 | 1768 |
//---------------------------------------------------------------- |
1769 |
// We can find true and false when PATH is null |
|
1770 |
//---------------------------------------------------------------- |
|
1771 |
try { |
|
1772 |
List<String> childArgs = new ArrayList<String>(javaChildArgs); |
|
1773 |
childArgs.add("null PATH"); |
|
1774 |
ProcessBuilder pb = new ProcessBuilder(childArgs); |
|
1775 |
pb.environment().remove("PATH"); |
|
2946
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
1776 |
ProcessResults r = run(pb); |
2 | 1777 |
equal(r.out(), ""); |
1778 |
equal(r.err(), ""); |
|
1779 |
equal(r.exitValue(), 0); |
|
1780 |
} catch (Throwable t) { unexpected(t); } |
|
1781 |
||
1782 |
//---------------------------------------------------------------- |
|
1783 |
// PATH search algorithm on Unix |
|
1784 |
//---------------------------------------------------------------- |
|
1785 |
try { |
|
1786 |
List<String> childArgs = new ArrayList<String>(javaChildArgs); |
|
1787 |
childArgs.add("PATH search algorithm"); |
|
1788 |
ProcessBuilder pb = new ProcessBuilder(childArgs); |
|
1789 |
pb.environment().put("PATH", "dir1:dir2:"); |
|
2946
f95752c3204a
6850720: (process) Use clone(CLONE_VM), not fork, on Linux to avoid swap exhaustion
martin
parents:
715
diff
changeset
|
1790 |
ProcessResults r = run(pb); |
2 | 1791 |
equal(r.out(), ""); |
1792 |
equal(r.err(), ""); |
|
1793 |
equal(r.exitValue(), True.exitValue()); |
|
1794 |
} catch (Throwable t) { unexpected(t); } |
|
1795 |
||
1796 |
//---------------------------------------------------------------- |
|
1797 |
// Parent's, not child's PATH is used |
|
1798 |
//---------------------------------------------------------------- |
|
1799 |
try { |
|
1800 |
new File("suBdiR").mkdirs(); |
|
1801 |
copy("/bin/true", "suBdiR/unliKely"); |
|
1802 |
final ProcessBuilder pb = |
|
1803 |
new ProcessBuilder(new String[]{"unliKely"}); |
|
1804 |
pb.environment().put("PATH", "suBdiR"); |
|
1805 |
THROWS(IOException.class, |
|
1806 |
new Fun() {void f() throws Throwable {pb.start();}}); |
|
1807 |
} catch (Throwable t) { unexpected(t); |
|
1808 |
} finally { |
|
1809 |
new File("suBdiR/unliKely").delete(); |
|
1810 |
new File("suBdiR").delete(); |
|
1811 |
} |
|
1812 |
} |
|
1813 |
||
1814 |
//---------------------------------------------------------------- |
|
1815 |
// Attempt to start bogus program "" |
|
1816 |
//---------------------------------------------------------------- |
|
1817 |
try { |
|
1818 |
new ProcessBuilder("").start(); |
|
1819 |
fail("Expected IOException not thrown"); |
|
1820 |
} catch (IOException e) { |
|
1821 |
String m = e.getMessage(); |
|
1822 |
if (EnglishUnix.is() && |
|
1823 |
! matches(m, "No such file or directory")) |
|
1824 |
unexpected(e); |
|
1825 |
} catch (Throwable t) { unexpected(t); } |
|
1826 |
||
1827 |
//---------------------------------------------------------------- |
|
1828 |
// Check that attempt to execute program name with funny |
|
1829 |
// characters throws an exception containing those characters. |
|
1830 |
//---------------------------------------------------------------- |
|
1831 |
for (String programName : new String[] {"\u00f0", "\u01f0"}) |
|
1832 |
try { |
|
1833 |
new ProcessBuilder(programName).start(); |
|
1834 |
fail("Expected IOException not thrown"); |
|
1835 |
} catch (IOException e) { |
|
1836 |
String m = e.getMessage(); |
|
1837 |
Pattern p = Pattern.compile(programName); |
|
1838 |
if (! matches(m, programName) |
|
1839 |
|| (EnglishUnix.is() |
|
1840 |
&& ! matches(m, "No such file or directory"))) |
|
1841 |
unexpected(e); |
|
1842 |
} catch (Throwable t) { unexpected(t); } |
|
1843 |
||
1844 |
//---------------------------------------------------------------- |
|
1845 |
// Attempt to start process in nonexistent directory fails. |
|
1846 |
//---------------------------------------------------------------- |
|
1847 |
try { |
|
1848 |
new ProcessBuilder("echo") |
|
1849 |
.directory(new File("UnLiKeLY")) |
|
1850 |
.start(); |
|
1851 |
fail("Expected IOException not thrown"); |
|
1852 |
} catch (IOException e) { |
|
1853 |
String m = e.getMessage(); |
|
1854 |
if (! matches(m, "in directory") |
|
1855 |
|| (EnglishUnix.is() && |
|
1856 |
! matches(m, "No such file or directory"))) |
|
1857 |
unexpected(e); |
|
1858 |
} catch (Throwable t) { unexpected(t); } |
|
1859 |
||
1860 |
//---------------------------------------------------------------- |
|
5786
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1861 |
// Attempt to write 4095 bytes to the pipe buffer without a |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1862 |
// reader to drain it would deadlock, if not for the fact that |
2 | 1863 |
// interprocess pipe buffers are at least 4096 bytes. |
5786
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1864 |
// |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1865 |
// Also, check that available reports all the bytes expected |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1866 |
// in the pipe buffer, and that I/O operations do the expected |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1867 |
// things. |
2 | 1868 |
//---------------------------------------------------------------- |
1869 |
try { |
|
1870 |
List<String> childArgs = new ArrayList<String>(javaChildArgs); |
|
1871 |
childArgs.add("print4095"); |
|
5786
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1872 |
final int SIZE = 4095; |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1873 |
final Process p = new ProcessBuilder(childArgs).start(); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1874 |
print4095(p.getOutputStream(), (byte) '!'); // Might hang! |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1875 |
p.waitFor(); // Might hang! |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1876 |
equal(SIZE, p.getInputStream().available()); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1877 |
equal(SIZE, p.getErrorStream().available()); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1878 |
THROWS(IOException.class, |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1879 |
new Fun(){void f() throws IOException { |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1880 |
p.getOutputStream().write((byte) '!'); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1881 |
p.getOutputStream().flush(); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1882 |
}}); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1883 |
|
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1884 |
final byte[] bytes = new byte[SIZE + 1]; |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1885 |
equal(SIZE, p.getInputStream().read(bytes)); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1886 |
for (int i = 0; i < SIZE; i++) |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1887 |
equal((byte) '!', bytes[i]); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1888 |
equal((byte) 0, bytes[SIZE]); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1889 |
|
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1890 |
equal(SIZE, p.getErrorStream().read(bytes)); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1891 |
for (int i = 0; i < SIZE; i++) |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1892 |
equal((byte) 'E', bytes[i]); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1893 |
equal((byte) 0, bytes[SIZE]); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1894 |
|
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1895 |
equal(0, p.getInputStream().available()); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1896 |
equal(0, p.getErrorStream().available()); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1897 |
equal(-1, p.getErrorStream().read()); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1898 |
equal(-1, p.getInputStream().read()); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1899 |
|
2 | 1900 |
equal(p.exitValue(), 5); |
5786
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1901 |
|
8540
ed028ce13912
7021327: Changes for 7020888 included changes to other files in error
alanb
parents:
8539
diff
changeset
|
1902 |
p.getInputStream().close(); |
ed028ce13912
7021327: Changes for 7020888 included changes to other files in error
alanb
parents:
8539
diff
changeset
|
1903 |
p.getErrorStream().close(); |
10347
1c9efe1ec7d3
7015589: (spec) BufferedWriter.close leaves stream open if close of underlying Writer fails
alanb
parents:
9500
diff
changeset
|
1904 |
try { p.getOutputStream().close(); } catch (IOException flushFailed) { } |
5786
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1905 |
|
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1906 |
InputStream[] streams = { p.getInputStream(), p.getErrorStream() }; |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1907 |
for (final InputStream in : streams) { |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1908 |
Fun[] ops = { |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1909 |
new Fun(){void f() throws IOException { |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1910 |
in.read(); }}, |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1911 |
new Fun(){void f() throws IOException { |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1912 |
in.read(bytes); }}, |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1913 |
new Fun(){void f() throws IOException { |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1914 |
in.available(); }} |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1915 |
}; |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1916 |
for (Fun op : ops) { |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1917 |
try { |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1918 |
op.f(); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1919 |
fail(); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1920 |
} catch (IOException expected) { |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1921 |
check(expected.getMessage() |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1922 |
.matches("[Ss]tream [Cc]losed")); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1923 |
} |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1924 |
} |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1925 |
} |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1926 |
} catch (Throwable t) { unexpected(t); } |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1927 |
|
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1928 |
//---------------------------------------------------------------- |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1929 |
// Check that reads which are pending when Process.destroy is |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1930 |
// called, get EOF, not IOException("Stream closed"). |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1931 |
//---------------------------------------------------------------- |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1932 |
try { |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1933 |
final int cases = 4; |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1934 |
for (int i = 0; i < cases; i++) { |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1935 |
final int action = i; |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1936 |
List<String> childArgs = new ArrayList<String>(javaChildArgs); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1937 |
childArgs.add("sleep"); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1938 |
final byte[] bytes = new byte[10]; |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1939 |
final Process p = new ProcessBuilder(childArgs).start(); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1940 |
final CountDownLatch latch = new CountDownLatch(1); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1941 |
final Thread thread = new Thread() { |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1942 |
public void run() { |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1943 |
try { |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1944 |
latch.countDown(); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1945 |
int r; |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1946 |
switch (action) { |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1947 |
case 0: r = p.getInputStream().read(); break; |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1948 |
case 1: r = p.getErrorStream().read(); break; |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1949 |
case 2: r = p.getInputStream().read(bytes); break; |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1950 |
case 3: r = p.getErrorStream().read(bytes); break; |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1951 |
default: throw new Error(); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1952 |
} |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1953 |
equal(-1, r); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1954 |
} catch (Throwable t) { unexpected(t); }}}; |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1955 |
|
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1956 |
thread.start(); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1957 |
latch.await(); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1958 |
Thread.sleep(10); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1959 |
p.destroy(); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1960 |
thread.join(); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5627
diff
changeset
|
1961 |
} |
2 | 1962 |
} catch (Throwable t) { unexpected(t); } |
1963 |
||
1964 |
//---------------------------------------------------------------- |
|
6669
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1965 |
// Check that subprocesses which create subprocesses of their |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1966 |
// own do not cause parent to hang waiting for file |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1967 |
// descriptors to be closed. |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1968 |
//---------------------------------------------------------------- |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1969 |
try { |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1970 |
if (Unix.is() |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1971 |
&& new File("/bin/bash").exists() |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1972 |
&& new File("/bin/sleep").exists()) { |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1973 |
final String[] cmd = { "/bin/bash", "-c", "(/bin/sleep 6666)" }; |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1974 |
final ProcessBuilder pb = new ProcessBuilder(cmd); |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1975 |
final Process p = pb.start(); |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1976 |
final InputStream stdout = p.getInputStream(); |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1977 |
final InputStream stderr = p.getErrorStream(); |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1978 |
final OutputStream stdin = p.getOutputStream(); |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1979 |
final Thread reader = new Thread() { |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1980 |
public void run() { |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1981 |
try { stdout.read(); } |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1982 |
catch (IOException e) { |
6849
02dc13de9152
6989903: (process) test/java/lang/ProcessBuilder/Basic.java failing with "Bad file number" (sol)
alanb
parents:
6669
diff
changeset
|
1983 |
// Check that reader failed because stream was |
02dc13de9152
6989903: (process) test/java/lang/ProcessBuilder/Basic.java failing with "Bad file number" (sol)
alanb
parents:
6669
diff
changeset
|
1984 |
// asynchronously closed. |
6669
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1985 |
// e.printStackTrace(); |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1986 |
if (EnglishUnix.is() && |
6849
02dc13de9152
6989903: (process) test/java/lang/ProcessBuilder/Basic.java failing with "Bad file number" (sol)
alanb
parents:
6669
diff
changeset
|
1987 |
! (e.getMessage().matches(".*Bad file.*"))) |
6669
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1988 |
unexpected(e); |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1989 |
} |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1990 |
catch (Throwable t) { unexpected(t); }}}; |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1991 |
reader.setDaemon(true); |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1992 |
reader.start(); |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1993 |
Thread.sleep(100); |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1994 |
p.destroy(); |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1995 |
// Subprocess is now dead, but file descriptors remain open. |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1996 |
check(p.waitFor() != 0); |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1997 |
check(p.exitValue() != 0); |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1998 |
stdout.close(); |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
1999 |
stderr.close(); |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2000 |
stdin.close(); |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2001 |
//---------------------------------------------------------- |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2002 |
// There remain unsolved issues with asynchronous close. |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2003 |
// Here's a highly non-portable experiment to demonstrate: |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2004 |
//---------------------------------------------------------- |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2005 |
if (Boolean.getBoolean("wakeupJeff!")) { |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2006 |
System.out.println("wakeupJeff!"); |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2007 |
// Initialize signal handler for INTERRUPT_SIGNAL. |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2008 |
new FileInputStream("/bin/sleep").getChannel().close(); |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2009 |
// Send INTERRUPT_SIGNAL to every thread in this java. |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2010 |
String[] wakeupJeff = { |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2011 |
"/bin/bash", "-c", |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2012 |
"/bin/ps --noheaders -Lfp $PPID | " + |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2013 |
"/usr/bin/perl -nale 'print $F[3]' | " + |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2014 |
// INTERRUPT_SIGNAL == 62 on my machine du jour. |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2015 |
"/usr/bin/xargs kill -62" |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2016 |
}; |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2017 |
new ProcessBuilder(wakeupJeff).start().waitFor(); |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2018 |
// If wakeupJeff worked, reader probably got EBADF. |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2019 |
reader.join(); |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2020 |
} |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2021 |
} |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2022 |
} catch (Throwable t) { unexpected(t); } |
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2023 |
|
8f8d4d5768ae
6981138: (process) Process.waitFor() may hang if subprocess has live descendants (lnx)
martin
parents:
5786
diff
changeset
|
2024 |
//---------------------------------------------------------------- |
2 | 2025 |
// Attempt to start process with insufficient permissions fails. |
2026 |
//---------------------------------------------------------------- |
|
2027 |
try { |
|
2028 |
new File("emptyCommand").delete(); |
|
2029 |
new FileOutputStream("emptyCommand").close(); |
|
2030 |
new File("emptyCommand").setExecutable(false); |
|
2031 |
new ProcessBuilder("./emptyCommand").start(); |
|
2032 |
fail("Expected IOException not thrown"); |
|
2033 |
} catch (IOException e) { |
|
2034 |
new File("./emptyCommand").delete(); |
|
2035 |
String m = e.getMessage(); |
|
2036 |
if (EnglishUnix.is() && |
|
2037 |
! matches(m, "Permission denied")) |
|
2038 |
unexpected(e); |
|
2039 |
} catch (Throwable t) { unexpected(t); } |
|
2040 |
||
2041 |
new File("emptyCommand").delete(); |
|
2042 |
||
2043 |
//---------------------------------------------------------------- |
|
2044 |
// Check for correct security permission behavior |
|
2045 |
//---------------------------------------------------------------- |
|
2046 |
final Policy policy = new Policy(); |
|
2047 |
Policy.setPolicy(policy); |
|
2048 |
System.setSecurityManager(new SecurityManager()); |
|
2049 |
||
2050 |
try { |
|
2051 |
// No permissions required to CREATE a ProcessBuilder |
|
2052 |
policy.setPermissions(/* Nothing */); |
|
2053 |
new ProcessBuilder("env").directory(null).directory(); |
|
2054 |
new ProcessBuilder("env").directory(new File("dir")).directory(); |
|
2055 |
new ProcessBuilder("env").command("??").command(); |
|
2056 |
} catch (Throwable t) { unexpected(t); } |
|
2057 |
||
2058 |
THROWS(SecurityException.class, |
|
2059 |
new Fun() { void f() throws IOException { |
|
2060 |
policy.setPermissions(/* Nothing */); |
|
2061 |
System.getenv("foo");}}, |
|
2062 |
new Fun() { void f() throws IOException { |
|
2063 |
policy.setPermissions(/* Nothing */); |
|
2064 |
System.getenv();}}, |
|
2065 |
new Fun() { void f() throws IOException { |
|
2066 |
policy.setPermissions(/* Nothing */); |
|
2067 |
new ProcessBuilder("echo").start();}}, |
|
2068 |
new Fun() { void f() throws IOException { |
|
2069 |
policy.setPermissions(/* Nothing */); |
|
2070 |
Runtime.getRuntime().exec("echo");}}, |
|
2071 |
new Fun() { void f() throws IOException { |
|
2072 |
policy.setPermissions(new RuntimePermission("getenv.bar")); |
|
2073 |
System.getenv("foo");}}); |
|
2074 |
||
2075 |
try { |
|
2076 |
policy.setPermissions(new RuntimePermission("getenv.foo")); |
|
2077 |
System.getenv("foo"); |
|
2078 |
||
2079 |
policy.setPermissions(new RuntimePermission("getenv.*")); |
|
2080 |
System.getenv("foo"); |
|
2081 |
System.getenv(); |
|
2082 |
new ProcessBuilder().environment(); |
|
2083 |
} catch (Throwable t) { unexpected(t); } |
|
2084 |
||
2085 |
||
2086 |
final Permission execPermission |
|
2087 |
= new FilePermission("<<ALL FILES>>", "execute"); |
|
2088 |
||
2089 |
THROWS(SecurityException.class, |
|
2090 |
new Fun() { void f() throws IOException { |
|
2091 |
// environment permission by itself insufficient |
|
2092 |
policy.setPermissions(new RuntimePermission("getenv.*")); |
|
2093 |
ProcessBuilder pb = new ProcessBuilder("env"); |
|
2094 |
pb.environment().put("foo","bar"); |
|
2095 |
pb.start();}}, |
|
2096 |
new Fun() { void f() throws IOException { |
|
2097 |
// exec permission by itself insufficient |
|
2098 |
policy.setPermissions(execPermission); |
|
2099 |
ProcessBuilder pb = new ProcessBuilder("env"); |
|
2100 |
pb.environment().put("foo","bar"); |
|
2101 |
pb.start();}}); |
|
2102 |
||
2103 |
try { |
|
2104 |
// Both permissions? OK. |
|
2105 |
policy.setPermissions(new RuntimePermission("getenv.*"), |
|
2106 |
execPermission); |
|
2107 |
ProcessBuilder pb = new ProcessBuilder("env"); |
|
2108 |
pb.environment().put("foo","bar"); |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
2109 |
Process p = pb.start(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
2110 |
closeStreams(p); |
2 | 2111 |
} catch (IOException e) { // OK |
2112 |
} catch (Throwable t) { unexpected(t); } |
|
2113 |
||
2114 |
try { |
|
2115 |
// Don't need environment permission unless READING environment |
|
2116 |
policy.setPermissions(execPermission); |
|
2117 |
Runtime.getRuntime().exec("env", new String[]{}); |
|
2118 |
} catch (IOException e) { // OK |
|
2119 |
} catch (Throwable t) { unexpected(t); } |
|
2120 |
||
2121 |
try { |
|
2122 |
// Don't need environment permission unless READING environment |
|
2123 |
policy.setPermissions(execPermission); |
|
2124 |
new ProcessBuilder("env").start(); |
|
2125 |
} catch (IOException e) { // OK |
|
2126 |
} catch (Throwable t) { unexpected(t); } |
|
2127 |
||
2128 |
// Restore "normal" state without a security manager |
|
2129 |
policy.setPermissions(new RuntimePermission("setSecurityManager")); |
|
2130 |
System.setSecurityManager(null); |
|
2131 |
||
13149
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2132 |
//---------------------------------------------------------------- |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2133 |
// Check that Process.isAlive() & |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2134 |
// Process.waitFor(0, TimeUnit.MILLISECONDS) work as expected. |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2135 |
//---------------------------------------------------------------- |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2136 |
try { |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2137 |
List<String> childArgs = new ArrayList<String>(javaChildArgs); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2138 |
childArgs.add("sleep"); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2139 |
final Process p = new ProcessBuilder(childArgs).start(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2140 |
long start = System.nanoTime(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2141 |
if (!p.isAlive() || p.waitFor(0, TimeUnit.MILLISECONDS)) { |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2142 |
fail("Test failed: Process exited prematurely"); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2143 |
} |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2144 |
long end = System.nanoTime(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2145 |
// give waitFor(timeout) a wide berth (100ms) |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2146 |
if ((end - start) > 100000000) |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2147 |
fail("Test failed: waitFor took too long"); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2148 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2149 |
p.destroy(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2150 |
p.waitFor(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2151 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2152 |
if (p.isAlive() || |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2153 |
!p.waitFor(0, TimeUnit.MILLISECONDS)) |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2154 |
{ |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2155 |
fail("Test failed: Process still alive - please terminate " + |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2156 |
p.toString() + " manually"); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2157 |
} |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2158 |
} catch (Throwable t) { unexpected(t); } |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2159 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2160 |
//---------------------------------------------------------------- |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2161 |
// Check that Process.waitFor(timeout, TimeUnit.MILLISECONDS) |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2162 |
// works as expected. |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2163 |
//---------------------------------------------------------------- |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2164 |
try { |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2165 |
List<String> childArgs = new ArrayList<String>(javaChildArgs); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2166 |
childArgs.add("sleep"); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2167 |
final Process p = new ProcessBuilder(childArgs).start(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2168 |
long start = System.nanoTime(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2169 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2170 |
p.waitFor(1000, TimeUnit.MILLISECONDS); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2171 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2172 |
long end = System.nanoTime(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2173 |
if ((end - start) < 500000000) |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2174 |
fail("Test failed: waitFor didn't take long enough"); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2175 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2176 |
p.destroy(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2177 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2178 |
start = System.nanoTime(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2179 |
p.waitFor(1000, TimeUnit.MILLISECONDS); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2180 |
end = System.nanoTime(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2181 |
if ((end - start) > 100000000) |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2182 |
fail("Test failed: waitFor took too long on a dead process."); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2183 |
} catch (Throwable t) { unexpected(t); } |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2184 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2185 |
//---------------------------------------------------------------- |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2186 |
// Check that Process.waitFor(timeout, TimeUnit.MILLISECONDS) |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2187 |
// interrupt works as expected. |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2188 |
//---------------------------------------------------------------- |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2189 |
try { |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2190 |
List<String> childArgs = new ArrayList<String>(javaChildArgs); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2191 |
childArgs.add("sleep"); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2192 |
final Process p = new ProcessBuilder(childArgs).start(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2193 |
final long start = System.nanoTime(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2194 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2195 |
final Thread thread = new Thread() { |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2196 |
public void run() { |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2197 |
try { |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2198 |
try { |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2199 |
p.waitFor(10000, TimeUnit.MILLISECONDS); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2200 |
} catch (InterruptedException e) { |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2201 |
return; |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2202 |
} |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2203 |
fail("waitFor() wasn't interrupted"); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2204 |
} catch (Throwable t) { unexpected(t); }}}; |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2205 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2206 |
thread.start(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2207 |
Thread.sleep(1000); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2208 |
thread.interrupt(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2209 |
p.destroy(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2210 |
} catch (Throwable t) { unexpected(t); } |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2211 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2212 |
//---------------------------------------------------------------- |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2213 |
// Check the default implementation for |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2214 |
// Process.waitFor(long, TimeUnit) |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2215 |
//---------------------------------------------------------------- |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2216 |
try { |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2217 |
List<String> childArgs = new ArrayList<String>(javaChildArgs); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2218 |
childArgs.add("sleep"); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2219 |
final Process proc = new ProcessBuilder(childArgs).start(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2220 |
DelegatingProcess p = new DelegatingProcess(proc); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2221 |
long start = System.nanoTime(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2222 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2223 |
p.waitFor(1000, TimeUnit.MILLISECONDS); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2224 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2225 |
long end = System.nanoTime(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2226 |
if ((end - start) < 500000000) |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2227 |
fail("Test failed: waitFor didn't take long enough"); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2228 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2229 |
p.destroy(); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2230 |
|
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2231 |
p.waitFor(1000, TimeUnit.MILLISECONDS); |
27d52f97a5cc
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
robm
parents:
12882
diff
changeset
|
2232 |
} catch (Throwable t) { unexpected(t); } |
2 | 2233 |
} |
2234 |
||
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
2235 |
static void closeStreams(Process p) { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
2236 |
try { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
2237 |
p.getOutputStream().close(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
2238 |
p.getInputStream().close(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
2239 |
p.getErrorStream().close(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
2240 |
} catch (Throwable t) { unexpected(t); } |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
2241 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
2242 |
|
2 | 2243 |
//---------------------------------------------------------------- |
2244 |
// A Policy class designed to make permissions fiddling very easy. |
|
2245 |
//---------------------------------------------------------------- |
|
2246 |
private static class Policy extends java.security.Policy { |
|
2247 |
private Permissions perms; |
|
2248 |
||
2249 |
public void setPermissions(Permission...permissions) { |
|
2250 |
perms = new Permissions(); |
|
2251 |
for (Permission permission : permissions) |
|
2252 |
perms.add(permission); |
|
2253 |
} |
|
2254 |
||
2255 |
public Policy() { setPermissions(/* Nothing */); } |
|
2256 |
||
2257 |
public PermissionCollection getPermissions(CodeSource cs) { |
|
2258 |
return perms; |
|
2259 |
} |
|
2260 |
||
2261 |
public PermissionCollection getPermissions(ProtectionDomain pd) { |
|
2262 |
return perms; |
|
2263 |
} |
|
2264 |
||
2265 |
public boolean implies(ProtectionDomain pd, Permission p) { |
|
2266 |
return perms.implies(p); |
|
2267 |
} |
|
2268 |
||
2269 |
public void refresh() {} |
|
2270 |
} |
|
2271 |
||
2272 |
private static class StreamAccumulator extends Thread { |
|
2273 |
private final InputStream is; |
|
2274 |
private final StringBuilder sb = new StringBuilder(); |
|
2275 |
private Throwable throwable = null; |
|
2276 |
||
2277 |
public String result () throws Throwable { |
|
2278 |
if (throwable != null) |
|
2279 |
throw throwable; |
|
2280 |
return sb.toString(); |
|
2281 |
} |
|
2282 |
||
2283 |
StreamAccumulator (InputStream is) { |
|
2284 |
this.is = is; |
|
2285 |
} |
|
2286 |
||
2287 |
public void run() { |
|
2288 |
try { |
|
2289 |
Reader r = new InputStreamReader(is); |
|
2290 |
char[] buf = new char[4096]; |
|
2291 |
int n; |
|
2292 |
while ((n = r.read(buf)) > 0) { |
|
2293 |
sb.append(buf,0,n); |
|
2294 |
} |
|
2295 |
} catch (Throwable t) { |
|
2296 |
throwable = t; |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
2297 |
} finally { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
2298 |
try { is.close(); } |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
2299 |
catch (Throwable t) { throwable = t; } |
2 | 2300 |
} |
2301 |
} |
|
2302 |
} |
|
2303 |
||
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
2304 |
static ProcessResults run(ProcessBuilder pb) { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
2305 |
try { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
2306 |
return run(pb.start()); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
2307 |
} catch (Throwable t) { unexpected(t); return null; } |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
2308 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
2309 |
|
2 | 2310 |
private static ProcessResults run(Process p) { |
2311 |
Throwable throwable = null; |
|
2312 |
int exitValue = -1; |
|
2313 |
String out = ""; |
|
2314 |
String err = ""; |
|
2315 |
||
2316 |
StreamAccumulator outAccumulator = |
|
2317 |
new StreamAccumulator(p.getInputStream()); |
|
2318 |
StreamAccumulator errAccumulator = |
|
2319 |
new StreamAccumulator(p.getErrorStream()); |
|
2320 |
||
2321 |
try { |
|
2322 |
outAccumulator.start(); |
|
2323 |
errAccumulator.start(); |
|
2324 |
||
2325 |
exitValue = p.waitFor(); |
|
2326 |
||
2327 |
outAccumulator.join(); |
|
2328 |
errAccumulator.join(); |
|
2329 |
||
2330 |
out = outAccumulator.result(); |
|
2331 |
err = errAccumulator.result(); |
|
2332 |
} catch (Throwable t) { |
|
2333 |
throwable = t; |
|
2334 |
} |
|
2335 |
||
2336 |
return new ProcessResults(out, err, exitValue, throwable); |
|
2337 |
} |
|
2338 |
||
2339 |
//---------------------------------------------------------------- |
|
2340 |
// Results of a command |
|
2341 |
//---------------------------------------------------------------- |
|
2342 |
private static class ProcessResults { |
|
2343 |
private final String out; |
|
2344 |
private final String err; |
|
2345 |
private final int exitValue; |
|
2346 |
private final Throwable throwable; |
|
2347 |
||
2348 |
public ProcessResults(String out, |
|
2349 |
String err, |
|
2350 |
int exitValue, |
|
2351 |
Throwable throwable) { |
|
2352 |
this.out = out; |
|
2353 |
this.err = err; |
|
2354 |
this.exitValue = exitValue; |
|
2355 |
this.throwable = throwable; |
|
2356 |
} |
|
2357 |
||
2358 |
public String out() { return out; } |
|
2359 |
public String err() { return err; } |
|
2360 |
public int exitValue() { return exitValue; } |
|
2361 |
public Throwable throwable() { return throwable; } |
|
2362 |
||
2363 |
public String toString() { |
|
2364 |
StringBuilder sb = new StringBuilder(); |
|
2365 |
sb.append("<STDOUT>\n" + out() + "</STDOUT>\n") |
|
2366 |
.append("<STDERR>\n" + err() + "</STDERR>\n") |
|
2367 |
.append("exitValue = " + exitValue + "\n"); |
|
2368 |
if (throwable != null) |
|
2369 |
sb.append(throwable.getStackTrace()); |
|
2370 |
return sb.toString(); |
|
2371 |
} |
|
2372 |
} |
|
2373 |
||
2374 |
//--------------------- Infrastructure --------------------------- |
|
2375 |
static volatile int passed = 0, failed = 0; |
|
2376 |
static void pass() {passed++;} |
|
2377 |
static void fail() {failed++; Thread.dumpStack();} |
|
2378 |
static void fail(String msg) {System.out.println(msg); fail();} |
|
2379 |
static void unexpected(Throwable t) {failed++; t.printStackTrace();} |
|
2380 |
static void check(boolean cond) {if (cond) pass(); else fail();} |
|
2381 |
static void check(boolean cond, String m) {if (cond) pass(); else fail(m);} |
|
2382 |
static void equal(Object x, Object y) { |
|
2383 |
if (x == null ? y == null : x.equals(y)) pass(); |
|
2384 |
else fail(x + " not equal to " + y);} |
|
8561
ca8d6ccdd9dc
7018606: (process) test/java/lang/ProcessBuilder/Basic.java failing intermittently (win)
michaelm
parents:
8540
diff
changeset
|
2385 |
|
2 | 2386 |
public static void main(String[] args) throws Throwable { |
2387 |
try {realMain(args);} catch (Throwable t) {unexpected(t);} |
|
2388 |
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); |
|
2389 |
if (failed > 0) throw new AssertionError("Some tests failed");} |
|
2390 |
private static abstract class Fun {abstract void f() throws Throwable;} |
|
2391 |
static void THROWS(Class<? extends Throwable> k, Fun... fs) { |
|
2392 |
for (Fun f : fs) |
|
2393 |
try { f.f(); fail("Expected " + k.getName() + " not thrown"); } |
|
2394 |
catch (Throwable t) { |
|
2395 |
if (k.isAssignableFrom(t.getClass())) pass(); |
|
2396 |
else unexpected(t);}} |
|
2397 |
} |