author | alanb |
Thu, 01 Dec 2016 08:57:53 +0000 | |
changeset 42338 | a60f280f803c |
parent 37781 | 71ed5645f17c |
child 44263 | 7a9297d467e7 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
32763
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
2 |
* Copyright (c) 2003, 2015, 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 |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 10 |
* |
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
||
26 |
package java.lang; |
|
27 |
||
28 |
import java.io.File; |
|
33826
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
29 |
import java.io.FileDescriptor; |
2 | 30 |
import java.io.IOException; |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
31 |
import java.io.InputStream; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
32 |
import java.io.OutputStream; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
33 |
import java.util.Arrays; |
2 | 34 |
import java.util.ArrayList; |
35 |
import java.util.List; |
|
36 |
import java.util.Map; |
|
37593
824750ada3d6
8154231: Simplify access to System properties from JDK code
redestad
parents:
35978
diff
changeset
|
37 |
import sun.security.action.GetPropertyAction; |
824750ada3d6
8154231: Simplify access to System properties from JDK code
redestad
parents:
35978
diff
changeset
|
38 |
|
2 | 39 |
/** |
40 |
* This class is used to create operating system processes. |
|
41 |
* |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
42 |
* <p>Each {@code ProcessBuilder} instance manages a collection |
2 | 43 |
* of process attributes. The {@link #start()} method creates a new |
44 |
* {@link Process} instance with those attributes. The {@link |
|
45 |
* #start()} method can be invoked repeatedly from the same instance |
|
46 |
* to create new subprocesses with identical or related attributes. |
|
33826
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
47 |
* <p> |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
48 |
* The {@link #startPipeline startPipeline} method can be invoked to create |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
49 |
* a pipeline of new processes that send the output of each process |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
50 |
* directly to the next process. Each process has the attributes of |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
51 |
* its respective ProcessBuilder. |
2 | 52 |
* |
53 |
* <p>Each process builder manages these process attributes: |
|
54 |
* |
|
55 |
* <ul> |
|
56 |
* |
|
57 |
* <li>a <i>command</i>, a list of strings which signifies the |
|
58 |
* external program file to be invoked and its arguments, if any. |
|
59 |
* Which string lists represent a valid operating system command is |
|
60 |
* system-dependent. For example, it is common for each conceptual |
|
61 |
* argument to be an element in this list, but there are operating |
|
62 |
* systems where programs are expected to tokenize command line |
|
63 |
* strings themselves - on such a system a Java implementation might |
|
64 |
* require commands to contain exactly two elements. |
|
65 |
* |
|
66 |
* <li>an <i>environment</i>, which is a system-dependent mapping from |
|
67 |
* <i>variables</i> to <i>values</i>. The initial value is a copy of |
|
68 |
* the environment of the current process (see {@link System#getenv()}). |
|
69 |
* |
|
70 |
* <li>a <i>working directory</i>. The default value is the current |
|
71 |
* working directory of the current process, usually the directory |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
72 |
* named by the system property {@code user.dir}. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
73 |
* |
18776 | 74 |
* <li><a name="redirect-input">a source of <i>standard input</i></a>. |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
75 |
* By default, the subprocess reads input from a pipe. Java code |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
76 |
* can access this pipe via the output stream returned by |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
77 |
* {@link Process#getOutputStream()}. However, standard input may |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
78 |
* be redirected to another source using |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
79 |
* {@link #redirectInput(Redirect) redirectInput}. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
80 |
* In this case, {@link Process#getOutputStream()} will return a |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
81 |
* <i>null output stream</i>, for which: |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
82 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
83 |
* <ul> |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
84 |
* <li>the {@link OutputStream#write(int) write} methods always |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
85 |
* throw {@code IOException} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
86 |
* <li>the {@link OutputStream#close() close} method does nothing |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
87 |
* </ul> |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
88 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
89 |
* <li><a name="redirect-output">a destination for <i>standard output</i> |
18776 | 90 |
* and <i>standard error</i></a>. By default, the subprocess writes standard |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
91 |
* output and standard error to pipes. Java code can access these pipes |
29601
d6e9fbd8497a
8073220: A typo in the documentation for class ProcessBuilder
rriggs
parents:
29600
diff
changeset
|
92 |
* via the input streams returned by {@link Process#getOutputStream()} and |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
93 |
* {@link Process#getErrorStream()}. However, standard output and |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
94 |
* standard error may be redirected to other destinations using |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
95 |
* {@link #redirectOutput(Redirect) redirectOutput} and |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
96 |
* {@link #redirectError(Redirect) redirectError}. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
97 |
* In this case, {@link Process#getInputStream()} and/or |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
98 |
* {@link Process#getErrorStream()} will return a <i>null input |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
99 |
* stream</i>, for which: |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
100 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
101 |
* <ul> |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
102 |
* <li>the {@link InputStream#read() read} methods always return |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
103 |
* {@code -1} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
104 |
* <li>the {@link InputStream#available() available} method always returns |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
105 |
* {@code 0} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
106 |
* <li>the {@link InputStream#close() close} method does nothing |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
107 |
* </ul> |
2 | 108 |
* |
109 |
* <li>a <i>redirectErrorStream</i> property. Initially, this property |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
110 |
* is {@code false}, meaning that the standard output and error |
2 | 111 |
* output of a subprocess are sent to two separate streams, which can |
112 |
* be accessed using the {@link Process#getInputStream()} and {@link |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
113 |
* Process#getErrorStream()} methods. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
114 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
115 |
* <p>If the value is set to {@code true}, then: |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
116 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
117 |
* <ul> |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
118 |
* <li>standard error is merged with the standard output and always sent |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
119 |
* to the same destination (this makes it easier to correlate error |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
120 |
* messages with the corresponding output) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
121 |
* <li>the common destination of standard error and standard output can be |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
122 |
* redirected using |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
123 |
* {@link #redirectOutput(Redirect) redirectOutput} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
124 |
* <li>any redirection set by the |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
125 |
* {@link #redirectError(Redirect) redirectError} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
126 |
* method is ignored when creating a subprocess |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
127 |
* <li>the stream returned from {@link Process#getErrorStream()} will |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
128 |
* always be a <a href="#redirect-output">null input stream</a> |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
129 |
* </ul> |
2 | 130 |
* |
131 |
* </ul> |
|
132 |
* |
|
133 |
* <p>Modifying a process builder's attributes will affect processes |
|
134 |
* subsequently started by that object's {@link #start()} method, but |
|
135 |
* will never affect previously started processes or the Java process |
|
136 |
* itself. |
|
137 |
* |
|
138 |
* <p>Most error checking is performed by the {@link #start()} method. |
|
139 |
* It is possible to modify the state of an object so that {@link |
|
140 |
* #start()} will fail. For example, setting the command attribute to |
|
141 |
* an empty list will not throw an exception unless {@link #start()} |
|
142 |
* is invoked. |
|
143 |
* |
|
144 |
* <p><strong>Note that this class is not synchronized.</strong> |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
145 |
* If multiple threads access a {@code ProcessBuilder} instance |
2 | 146 |
* concurrently, and at least one of the threads modifies one of the |
147 |
* attributes structurally, it <i>must</i> be synchronized externally. |
|
148 |
* |
|
149 |
* <p>Starting a new process which uses the default working directory |
|
150 |
* and environment is easy: |
|
151 |
* |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
152 |
* <pre> {@code |
2 | 153 |
* Process p = new ProcessBuilder("myCommand", "myArg").start(); |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
154 |
* }</pre> |
2 | 155 |
* |
156 |
* <p>Here is an example that starts a process with a modified working |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
157 |
* directory and environment, and redirects standard output and error |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
158 |
* to be appended to a log file: |
2 | 159 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
160 |
* <pre> {@code |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
161 |
* ProcessBuilder pb = |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
162 |
* new ProcessBuilder("myCommand", "myArg1", "myArg2"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
163 |
* Map<String, String> env = pb.environment(); |
2 | 164 |
* env.put("VAR1", "myValue"); |
165 |
* env.remove("OTHERVAR"); |
|
166 |
* env.put("VAR2", env.get("VAR1") + "suffix"); |
|
167 |
* pb.directory(new File("myDir")); |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
168 |
* File log = new File("log"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
169 |
* pb.redirectErrorStream(true); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
170 |
* pb.redirectOutput(Redirect.appendTo(log)); |
2 | 171 |
* Process p = pb.start(); |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
172 |
* assert pb.redirectInput() == Redirect.PIPE; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
173 |
* assert pb.redirectOutput().file() == log; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
174 |
* assert p.getInputStream().read() == -1; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
175 |
* }</pre> |
2 | 176 |
* |
177 |
* <p>To start a process with an explicit set of environment |
|
178 |
* variables, first call {@link java.util.Map#clear() Map.clear()} |
|
179 |
* before adding environment variables. |
|
180 |
* |
|
29381
6d4ed10391a6
8058464: (process spec) ProcessBuilder.redirectXXX throws unspecified NPE
rriggs
parents:
28872
diff
changeset
|
181 |
* <p> |
6d4ed10391a6
8058464: (process spec) ProcessBuilder.redirectXXX throws unspecified NPE
rriggs
parents:
28872
diff
changeset
|
182 |
* Unless otherwise noted, passing a {@code null} argument to a constructor |
6d4ed10391a6
8058464: (process spec) ProcessBuilder.redirectXXX throws unspecified NPE
rriggs
parents:
28872
diff
changeset
|
183 |
* or method in this class will cause a {@link NullPointerException} to be |
6d4ed10391a6
8058464: (process spec) ProcessBuilder.redirectXXX throws unspecified NPE
rriggs
parents:
28872
diff
changeset
|
184 |
* thrown. |
6d4ed10391a6
8058464: (process spec) ProcessBuilder.redirectXXX throws unspecified NPE
rriggs
parents:
28872
diff
changeset
|
185 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
186 |
* @author Martin Buchholz |
2 | 187 |
* @since 1.5 |
188 |
*/ |
|
189 |
||
190 |
public final class ProcessBuilder |
|
191 |
{ |
|
192 |
private List<String> command; |
|
193 |
private File directory; |
|
194 |
private Map<String,String> environment; |
|
195 |
private boolean redirectErrorStream; |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
196 |
private Redirect[] redirects; |
2 | 197 |
|
198 |
/** |
|
199 |
* Constructs a process builder with the specified operating |
|
200 |
* system program and arguments. This constructor does <i>not</i> |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
201 |
* make a copy of the {@code command} list. Subsequent |
2 | 202 |
* updates to the list will be reflected in the state of the |
203 |
* process builder. It is not checked whether |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
204 |
* {@code command} corresponds to a valid operating system |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
205 |
* command. |
2 | 206 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
207 |
* @param command the list containing the program and its arguments |
2 | 208 |
*/ |
209 |
public ProcessBuilder(List<String> command) { |
|
210 |
if (command == null) |
|
211 |
throw new NullPointerException(); |
|
212 |
this.command = command; |
|
213 |
} |
|
214 |
||
215 |
/** |
|
216 |
* Constructs a process builder with the specified operating |
|
217 |
* system program and arguments. This is a convenience |
|
218 |
* constructor that sets the process builder's command to a string |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
219 |
* list containing the same strings as the {@code command} |
2 | 220 |
* array, in the same order. It is not checked whether |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
221 |
* {@code command} corresponds to a valid operating system |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
222 |
* command. |
2 | 223 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
224 |
* @param command a string array containing the program and its arguments |
2 | 225 |
*/ |
226 |
public ProcessBuilder(String... command) { |
|
7803
56bc97d69d93
6880112: Project Coin: Port JDK core library code to use diamond operator
smarks
parents:
7515
diff
changeset
|
227 |
this.command = new ArrayList<>(command.length); |
2 | 228 |
for (String arg : command) |
229 |
this.command.add(arg); |
|
230 |
} |
|
231 |
||
232 |
/** |
|
233 |
* Sets this process builder's operating system program and |
|
234 |
* arguments. This method does <i>not</i> make a copy of the |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
235 |
* {@code command} list. Subsequent updates to the list will |
2 | 236 |
* be reflected in the state of the process builder. It is not |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
237 |
* checked whether {@code command} corresponds to a valid |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
238 |
* operating system command. |
2 | 239 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
240 |
* @param command the list containing the program and its arguments |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
241 |
* @return this process builder |
2 | 242 |
*/ |
243 |
public ProcessBuilder command(List<String> command) { |
|
244 |
if (command == null) |
|
245 |
throw new NullPointerException(); |
|
246 |
this.command = command; |
|
247 |
return this; |
|
248 |
} |
|
249 |
||
250 |
/** |
|
251 |
* Sets this process builder's operating system program and |
|
252 |
* arguments. This is a convenience method that sets the command |
|
253 |
* to a string list containing the same strings as the |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
254 |
* {@code command} array, in the same order. It is not |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
255 |
* checked whether {@code command} corresponds to a valid |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
256 |
* operating system command. |
2 | 257 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
258 |
* @param command a string array containing the program and its arguments |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
259 |
* @return this process builder |
2 | 260 |
*/ |
261 |
public ProcessBuilder command(String... command) { |
|
7803
56bc97d69d93
6880112: Project Coin: Port JDK core library code to use diamond operator
smarks
parents:
7515
diff
changeset
|
262 |
this.command = new ArrayList<>(command.length); |
2 | 263 |
for (String arg : command) |
264 |
this.command.add(arg); |
|
265 |
return this; |
|
266 |
} |
|
267 |
||
268 |
/** |
|
269 |
* Returns this process builder's operating system program and |
|
270 |
* arguments. The returned list is <i>not</i> a copy. Subsequent |
|
271 |
* updates to the list will be reflected in the state of this |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
272 |
* process builder. |
2 | 273 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
274 |
* @return this process builder's program and its arguments |
2 | 275 |
*/ |
276 |
public List<String> command() { |
|
277 |
return command; |
|
278 |
} |
|
279 |
||
280 |
/** |
|
281 |
* Returns a string map view of this process builder's environment. |
|
282 |
* |
|
283 |
* Whenever a process builder is created, the environment is |
|
284 |
* initialized to a copy of the current process environment (see |
|
285 |
* {@link System#getenv()}). Subprocesses subsequently started by |
|
286 |
* this object's {@link #start()} method will use this map as |
|
287 |
* their environment. |
|
288 |
* |
|
289 |
* <p>The returned object may be modified using ordinary {@link |
|
290 |
* java.util.Map Map} operations. These modifications will be |
|
291 |
* visible to subprocesses started via the {@link #start()} |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
292 |
* method. Two {@code ProcessBuilder} instances always |
2 | 293 |
* contain independent process environments, so changes to the |
294 |
* returned map will never be reflected in any other |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
295 |
* {@code ProcessBuilder} instance or the values returned by |
2 | 296 |
* {@link System#getenv System.getenv}. |
297 |
* |
|
298 |
* <p>If the system does not support environment variables, an |
|
299 |
* empty map is returned. |
|
300 |
* |
|
301 |
* <p>The returned map does not permit null keys or values. |
|
302 |
* Attempting to insert or query the presence of a null key or |
|
303 |
* value will throw a {@link NullPointerException}. |
|
304 |
* Attempting to query the presence of a key or value which is not |
|
305 |
* of type {@link String} will throw a {@link ClassCastException}. |
|
306 |
* |
|
307 |
* <p>The behavior of the returned map is system-dependent. A |
|
308 |
* system may not allow modifications to environment variables or |
|
309 |
* may forbid certain variable names or values. For this reason, |
|
310 |
* attempts to modify the map may fail with |
|
311 |
* {@link UnsupportedOperationException} or |
|
312 |
* {@link IllegalArgumentException} |
|
313 |
* if the modification is not permitted by the operating system. |
|
314 |
* |
|
315 |
* <p>Since the external format of environment variable names and |
|
316 |
* values is system-dependent, there may not be a one-to-one |
|
317 |
* mapping between them and Java's Unicode strings. Nevertheless, |
|
318 |
* the map is implemented in such a way that environment variables |
|
319 |
* which are not modified by Java code will have an unmodified |
|
320 |
* native representation in the subprocess. |
|
321 |
* |
|
322 |
* <p>The returned map and its collection views may not obey the |
|
323 |
* general contract of the {@link Object#equals} and |
|
324 |
* {@link Object#hashCode} methods. |
|
325 |
* |
|
326 |
* <p>The returned map is typically case-sensitive on all platforms. |
|
327 |
* |
|
328 |
* <p>If a security manager exists, its |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
329 |
* {@link SecurityManager#checkPermission checkPermission} method |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
330 |
* is called with a |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
331 |
* {@link RuntimePermission}{@code ("getenv.*")} permission. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
332 |
* This may result in a {@link SecurityException} being thrown. |
2 | 333 |
* |
334 |
* <p>When passing information to a Java subprocess, |
|
335 |
* <a href=System.html#EnvironmentVSSystemProperties>system properties</a> |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
336 |
* are generally preferred over environment variables. |
2 | 337 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
338 |
* @return this process builder's environment |
2 | 339 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
340 |
* @throws SecurityException |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
341 |
* if a security manager exists and its |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
342 |
* {@link SecurityManager#checkPermission checkPermission} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
343 |
* method doesn't allow access to the process environment |
2 | 344 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
345 |
* @see Runtime#exec(String[],String[],java.io.File) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
346 |
* @see System#getenv() |
2 | 347 |
*/ |
348 |
public Map<String,String> environment() { |
|
349 |
SecurityManager security = System.getSecurityManager(); |
|
350 |
if (security != null) |
|
351 |
security.checkPermission(new RuntimePermission("getenv.*")); |
|
352 |
||
353 |
if (environment == null) |
|
354 |
environment = ProcessEnvironment.environment(); |
|
355 |
||
356 |
assert environment != null; |
|
357 |
||
358 |
return environment; |
|
359 |
} |
|
360 |
||
361 |
// Only for use by Runtime.exec(...envp...) |
|
362 |
ProcessBuilder environment(String[] envp) { |
|
363 |
assert environment == null; |
|
364 |
if (envp != null) { |
|
365 |
environment = ProcessEnvironment.emptyEnvironment(envp.length); |
|
366 |
assert environment != null; |
|
367 |
||
368 |
for (String envstring : envp) { |
|
369 |
// Before 1.5, we blindly passed invalid envstrings |
|
370 |
// to the child process. |
|
371 |
// We would like to throw an exception, but do not, |
|
372 |
// for compatibility with old broken code. |
|
373 |
||
374 |
// Silently discard any trailing junk. |
|
375 |
if (envstring.indexOf((int) '\u0000') != -1) |
|
376 |
envstring = envstring.replaceFirst("\u0000.*", ""); |
|
377 |
||
378 |
int eqlsign = |
|
379 |
envstring.indexOf('=', ProcessEnvironment.MIN_NAME_LENGTH); |
|
380 |
// Silently ignore envstrings lacking the required `='. |
|
381 |
if (eqlsign != -1) |
|
382 |
environment.put(envstring.substring(0,eqlsign), |
|
383 |
envstring.substring(eqlsign+1)); |
|
384 |
} |
|
385 |
} |
|
386 |
return this; |
|
387 |
} |
|
388 |
||
389 |
/** |
|
390 |
* Returns this process builder's working directory. |
|
391 |
* |
|
392 |
* Subprocesses subsequently started by this object's {@link |
|
393 |
* #start()} method will use this as their working directory. |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
394 |
* The returned value may be {@code null} -- this means to use |
2 | 395 |
* the working directory of the current Java process, usually the |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
396 |
* directory named by the system property {@code user.dir}, |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
397 |
* as the working directory of the child process. |
2 | 398 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
399 |
* @return this process builder's working directory |
2 | 400 |
*/ |
401 |
public File directory() { |
|
402 |
return directory; |
|
403 |
} |
|
404 |
||
405 |
/** |
|
406 |
* Sets this process builder's working directory. |
|
407 |
* |
|
408 |
* Subprocesses subsequently started by this object's {@link |
|
409 |
* #start()} method will use this as their working directory. |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
410 |
* The argument may be {@code null} -- this means to use the |
2 | 411 |
* working directory of the current Java process, usually the |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
412 |
* directory named by the system property {@code user.dir}, |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
413 |
* as the working directory of the child process. |
2 | 414 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
415 |
* @param directory the new working directory |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
416 |
* @return this process builder |
2 | 417 |
*/ |
418 |
public ProcessBuilder directory(File directory) { |
|
419 |
this.directory = directory; |
|
420 |
return this; |
|
421 |
} |
|
422 |
||
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
423 |
// ---------------- I/O Redirection ---------------- |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
424 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
425 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
426 |
* Implements a <a href="#redirect-output">null input stream</a>. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
427 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
428 |
static class NullInputStream extends InputStream { |
5786
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5506
diff
changeset
|
429 |
static final NullInputStream INSTANCE = new NullInputStream(); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5506
diff
changeset
|
430 |
private NullInputStream() {} |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
431 |
public int read() { return -1; } |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
432 |
public int available() { return 0; } |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
433 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
434 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
435 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
436 |
* Implements a <a href="#redirect-input">null output stream</a>. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
437 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
438 |
static class NullOutputStream extends OutputStream { |
5786
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5506
diff
changeset
|
439 |
static final NullOutputStream INSTANCE = new NullOutputStream(); |
f60ef38202e7
6944584: Improvements to subprocess handling on Unix
martin
parents:
5506
diff
changeset
|
440 |
private NullOutputStream() {} |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
441 |
public void write(int b) throws IOException { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
442 |
throw new IOException("Stream closed"); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
443 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
444 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
445 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
446 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
447 |
* Represents a source of subprocess input or a destination of |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
448 |
* subprocess output. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
449 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
450 |
* Each {@code Redirect} instance is one of the following: |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
451 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
452 |
* <ul> |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
453 |
* <li>the special value {@link #PIPE Redirect.PIPE} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
454 |
* <li>the special value {@link #INHERIT Redirect.INHERIT} |
32763
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
455 |
* <li>the special value {@link #DISCARD Redirect.DISCARD} |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
456 |
* <li>a redirection to read from a file, created by an invocation of |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
457 |
* {@link Redirect#from Redirect.from(File)} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
458 |
* <li>a redirection to write to a file, created by an invocation of |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
459 |
* {@link Redirect#to Redirect.to(File)} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
460 |
* <li>a redirection to append to a file, created by an invocation of |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
461 |
* {@link Redirect#appendTo Redirect.appendTo(File)} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
462 |
* </ul> |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
463 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
464 |
* <p>Each of the above categories has an associated unique |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
465 |
* {@link Type Type}. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
466 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
467 |
* @since 1.7 |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
468 |
*/ |
32649
2ee9017c7597
8136583: Core libraries should use blessed modifier order
martin
parents:
29601
diff
changeset
|
469 |
public abstract static class Redirect { |
37593
824750ada3d6
8154231: Simplify access to System properties from JDK code
redestad
parents:
35978
diff
changeset
|
470 |
private static final File NULL_FILE = new File( |
37781
71ed5645f17c
8155775: Re-examine naming of privileged methods to access System properties
redestad
parents:
37593
diff
changeset
|
471 |
(GetPropertyAction.privilegedGetProperty("os.name") |
37593
824750ada3d6
8154231: Simplify access to System properties from JDK code
redestad
parents:
35978
diff
changeset
|
472 |
.startsWith("Windows") ? "NUL" : "/dev/null") |
32763
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
473 |
); |
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
474 |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
475 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
476 |
* The type of a {@link Redirect}. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
477 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
478 |
public enum Type { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
479 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
480 |
* The type of {@link Redirect#PIPE Redirect.PIPE}. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
481 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
482 |
PIPE, |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
483 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
484 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
485 |
* The type of {@link Redirect#INHERIT Redirect.INHERIT}. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
486 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
487 |
INHERIT, |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
488 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
489 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
490 |
* The type of redirects returned from |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
491 |
* {@link Redirect#from Redirect.from(File)}. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
492 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
493 |
READ, |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
494 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
495 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
496 |
* The type of redirects returned from |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
497 |
* {@link Redirect#to Redirect.to(File)}. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
498 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
499 |
WRITE, |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
500 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
501 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
502 |
* The type of redirects returned from |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
503 |
* {@link Redirect#appendTo Redirect.appendTo(File)}. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
504 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
505 |
APPEND |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
506 |
}; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
507 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
508 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
509 |
* Returns the type of this {@code Redirect}. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
510 |
* @return the type of this {@code Redirect} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
511 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
512 |
public abstract Type type(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
513 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
514 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
515 |
* Indicates that subprocess I/O will be connected to the |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
516 |
* current Java process over a pipe. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
517 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
518 |
* This is the default handling of subprocess standard I/O. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
519 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
520 |
* <p>It will always be true that |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
521 |
* <pre> {@code |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
522 |
* Redirect.PIPE.file() == null && |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
523 |
* Redirect.PIPE.type() == Redirect.Type.PIPE |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
524 |
* }</pre> |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
525 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
526 |
public static final Redirect PIPE = new Redirect() { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
527 |
public Type type() { return Type.PIPE; } |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
528 |
public String toString() { return type().toString(); }}; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
529 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
530 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
531 |
* Indicates that subprocess I/O source or destination will be the |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
532 |
* same as those of the current process. This is the normal |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
533 |
* behavior of most operating system command interpreters (shells). |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
534 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
535 |
* <p>It will always be true that |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
536 |
* <pre> {@code |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
537 |
* Redirect.INHERIT.file() == null && |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
538 |
* Redirect.INHERIT.type() == Redirect.Type.INHERIT |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
539 |
* }</pre> |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
540 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
541 |
public static final Redirect INHERIT = new Redirect() { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
542 |
public Type type() { return Type.INHERIT; } |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
543 |
public String toString() { return type().toString(); }}; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
544 |
|
32763
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
545 |
|
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
546 |
/** |
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
547 |
* Indicates that subprocess output will be discarded. |
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
548 |
* A typical implementation discards the output by writing to |
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
549 |
* an operating system specific "null file". |
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
550 |
* |
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
551 |
* <p>It will always be true that |
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
552 |
* <pre> {@code |
35978
752d505da547
8148775: Spec for j.l.ProcessBuilder.Redirect.DISCARD need to be improved
rriggs
parents:
33826
diff
changeset
|
553 |
* Redirect.DISCARD.file() is the filename appropriate for the operating system |
32763
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
554 |
* and may be null && |
35978
752d505da547
8148775: Spec for j.l.ProcessBuilder.Redirect.DISCARD need to be improved
rriggs
parents:
33826
diff
changeset
|
555 |
* Redirect.DISCARD.type() == Redirect.Type.WRITE |
32763
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
556 |
* }</pre> |
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
557 |
* @since 9 |
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
558 |
*/ |
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
559 |
public static final Redirect DISCARD = new Redirect() { |
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
560 |
public Type type() { return Type.WRITE; } |
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
561 |
public String toString() { return type().toString(); } |
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
562 |
public File file() { return NULL_FILE; } |
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
563 |
boolean append() { return false; } |
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
564 |
}; |
c11c2b9b45a5
8132541: (process) ProcessBuilder support for redirection to discard output
rriggs
parents:
32649
diff
changeset
|
565 |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
566 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
567 |
* Returns the {@link File} source or destination associated |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
568 |
* with this redirect, or {@code null} if there is no such file. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
569 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
570 |
* @return the file associated with this redirect, |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
571 |
* or {@code null} if there is no such file |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
572 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
573 |
public File file() { return null; } |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
574 |
|
7515
43202796198e
6709457: (fc) lock/tryLock() throws IOException "Access is denied" when file opened for append [win]
alanb
parents:
5786
diff
changeset
|
575 |
/** |
43202796198e
6709457: (fc) lock/tryLock() throws IOException "Access is denied" when file opened for append [win]
alanb
parents:
5786
diff
changeset
|
576 |
* When redirected to a destination file, indicates if the output |
43202796198e
6709457: (fc) lock/tryLock() throws IOException "Access is denied" when file opened for append [win]
alanb
parents:
5786
diff
changeset
|
577 |
* is to be written to the end of the file. |
43202796198e
6709457: (fc) lock/tryLock() throws IOException "Access is denied" when file opened for append [win]
alanb
parents:
5786
diff
changeset
|
578 |
*/ |
43202796198e
6709457: (fc) lock/tryLock() throws IOException "Access is denied" when file opened for append [win]
alanb
parents:
5786
diff
changeset
|
579 |
boolean append() { |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
580 |
throw new UnsupportedOperationException(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
581 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
582 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
583 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
584 |
* Returns a redirect to read from the specified file. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
585 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
586 |
* <p>It will always be true that |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
587 |
* <pre> {@code |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
588 |
* Redirect.from(file).file() == file && |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
589 |
* Redirect.from(file).type() == Redirect.Type.READ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
590 |
* }</pre> |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
591 |
* |
18776 | 592 |
* @param file The {@code File} for the {@code Redirect}. |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
593 |
* @return a redirect to read from the specified file |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
594 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
595 |
public static Redirect from(final File file) { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
596 |
if (file == null) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
597 |
throw new NullPointerException(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
598 |
return new Redirect() { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
599 |
public Type type() { return Type.READ; } |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
600 |
public File file() { return file; } |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
601 |
public String toString() { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
602 |
return "redirect to read from file \"" + file + "\""; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
603 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
604 |
}; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
605 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
606 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
607 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
608 |
* Returns a redirect to write to the specified file. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
609 |
* If the specified file exists when the subprocess is started, |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
610 |
* its previous contents will be discarded. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
611 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
612 |
* <p>It will always be true that |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
613 |
* <pre> {@code |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
614 |
* Redirect.to(file).file() == file && |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
615 |
* Redirect.to(file).type() == Redirect.Type.WRITE |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
616 |
* }</pre> |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
617 |
* |
18776 | 618 |
* @param file The {@code File} for the {@code Redirect}. |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
619 |
* @return a redirect to write to the specified file |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
620 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
621 |
public static Redirect to(final File file) { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
622 |
if (file == null) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
623 |
throw new NullPointerException(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
624 |
return new Redirect() { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
625 |
public Type type() { return Type.WRITE; } |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
626 |
public File file() { return file; } |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
627 |
public String toString() { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
628 |
return "redirect to write to file \"" + file + "\""; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
629 |
} |
7515
43202796198e
6709457: (fc) lock/tryLock() throws IOException "Access is denied" when file opened for append [win]
alanb
parents:
5786
diff
changeset
|
630 |
boolean append() { return false; } |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
631 |
}; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
632 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
633 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
634 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
635 |
* Returns a redirect to append to the specified file. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
636 |
* Each write operation first advances the position to the |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
637 |
* end of the file and then writes the requested data. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
638 |
* Whether the advancement of the position and the writing |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
639 |
* of the data are done in a single atomic operation is |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
640 |
* system-dependent and therefore unspecified. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
641 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
642 |
* <p>It will always be true that |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
643 |
* <pre> {@code |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
644 |
* Redirect.appendTo(file).file() == file && |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
645 |
* Redirect.appendTo(file).type() == Redirect.Type.APPEND |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
646 |
* }</pre> |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
647 |
* |
18776 | 648 |
* @param file The {@code File} for the {@code Redirect}. |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
649 |
* @return a redirect to append to the specified file |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
650 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
651 |
public static Redirect appendTo(final File file) { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
652 |
if (file == null) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
653 |
throw new NullPointerException(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
654 |
return new Redirect() { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
655 |
public Type type() { return Type.APPEND; } |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
656 |
public File file() { return file; } |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
657 |
public String toString() { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
658 |
return "redirect to append to file \"" + file + "\""; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
659 |
} |
7515
43202796198e
6709457: (fc) lock/tryLock() throws IOException "Access is denied" when file opened for append [win]
alanb
parents:
5786
diff
changeset
|
660 |
boolean append() { return true; } |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
661 |
}; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
662 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
663 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
664 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
665 |
* Compares the specified object with this {@code Redirect} for |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
666 |
* equality. Returns {@code true} if and only if the two |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
667 |
* objects are identical or both objects are {@code Redirect} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
668 |
* instances of the same type associated with non-null equal |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
669 |
* {@code File} instances. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
670 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
671 |
public boolean equals(Object obj) { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
672 |
if (obj == this) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
673 |
return true; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
674 |
if (! (obj instanceof Redirect)) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
675 |
return false; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
676 |
Redirect r = (Redirect) obj; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
677 |
if (r.type() != this.type()) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
678 |
return false; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
679 |
assert this.file() != null; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
680 |
return this.file().equals(r.file()); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
681 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
682 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
683 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
684 |
* Returns a hash code value for this {@code Redirect}. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
685 |
* @return a hash code value for this {@code Redirect} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
686 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
687 |
public int hashCode() { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
688 |
File file = file(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
689 |
if (file == null) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
690 |
return super.hashCode(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
691 |
else |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
692 |
return file.hashCode(); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
693 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
694 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
695 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
696 |
* No public constructors. Clients must use predefined |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
697 |
* static {@code Redirect} instances or factory methods. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
698 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
699 |
private Redirect() {} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
700 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
701 |
|
33826
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
702 |
/** |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
703 |
* Private implementation subclass of Redirect that holds a FileDescriptor for the |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
704 |
* output of a previously started Process. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
705 |
* The FileDescriptor is used as the standard input of the next Process |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
706 |
* to be started. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
707 |
*/ |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
708 |
static class RedirectPipeImpl extends Redirect { |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
709 |
final FileDescriptor fd; |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
710 |
|
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
711 |
RedirectPipeImpl() { |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
712 |
this.fd = new FileDescriptor(); |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
713 |
} |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
714 |
@Override |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
715 |
public Type type() { return Type.PIPE; } |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
716 |
|
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
717 |
@Override |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
718 |
public String toString() { return type().toString();} |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
719 |
|
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
720 |
FileDescriptor getFd() { return fd; } |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
721 |
} |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
722 |
|
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
723 |
/** |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
724 |
* Return the array of redirects, creating the default as needed. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
725 |
* @return the array of redirects |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
726 |
*/ |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
727 |
private Redirect[] redirects() { |
33826
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
728 |
if (redirects == null) { |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
729 |
redirects = new Redirect[] { |
33826
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
730 |
Redirect.PIPE, Redirect.PIPE, Redirect.PIPE |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
731 |
}; |
33826
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
732 |
} |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
733 |
return redirects; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
734 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
735 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
736 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
737 |
* Sets this process builder's standard input source. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
738 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
739 |
* Subprocesses subsequently started by this object's {@link #start()} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
740 |
* method obtain their standard input from this source. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
741 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
742 |
* <p>If the source is {@link Redirect#PIPE Redirect.PIPE} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
743 |
* (the initial value), then the standard input of a |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
744 |
* subprocess can be written to using the output stream |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
745 |
* returned by {@link Process#getOutputStream()}. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
746 |
* If the source is set to any other value, then |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
747 |
* {@link Process#getOutputStream()} will return a |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
748 |
* <a href="#redirect-input">null output stream</a>. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
749 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
750 |
* @param source the new standard input source |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
751 |
* @return this process builder |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
752 |
* @throws IllegalArgumentException |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
753 |
* if the redirect does not correspond to a valid source |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
754 |
* of data, that is, has type |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
755 |
* {@link Redirect.Type#WRITE WRITE} or |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
756 |
* {@link Redirect.Type#APPEND APPEND} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
757 |
* @since 1.7 |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
758 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
759 |
public ProcessBuilder redirectInput(Redirect source) { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
760 |
if (source.type() == Redirect.Type.WRITE || |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
761 |
source.type() == Redirect.Type.APPEND) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
762 |
throw new IllegalArgumentException( |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
763 |
"Redirect invalid for reading: " + source); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
764 |
redirects()[0] = source; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
765 |
return this; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
766 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
767 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
768 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
769 |
* Sets this process builder's standard output destination. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
770 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
771 |
* Subprocesses subsequently started by this object's {@link #start()} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
772 |
* method send their standard output to this destination. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
773 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
774 |
* <p>If the destination is {@link Redirect#PIPE Redirect.PIPE} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
775 |
* (the initial value), then the standard output of a subprocess |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
776 |
* can be read using the input stream returned by {@link |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
777 |
* Process#getInputStream()}. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
778 |
* If the destination is set to any other value, then |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
779 |
* {@link Process#getInputStream()} will return a |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
780 |
* <a href="#redirect-output">null input stream</a>. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
781 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
782 |
* @param destination the new standard output destination |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
783 |
* @return this process builder |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
784 |
* @throws IllegalArgumentException |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
785 |
* if the redirect does not correspond to a valid |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
786 |
* destination of data, that is, has type |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
787 |
* {@link Redirect.Type#READ READ} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
788 |
* @since 1.7 |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
789 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
790 |
public ProcessBuilder redirectOutput(Redirect destination) { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
791 |
if (destination.type() == Redirect.Type.READ) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
792 |
throw new IllegalArgumentException( |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
793 |
"Redirect invalid for writing: " + destination); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
794 |
redirects()[1] = destination; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
795 |
return this; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
796 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
797 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
798 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
799 |
* Sets this process builder's standard error destination. |
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 |
* Subprocesses subsequently started by this object's {@link #start()} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
802 |
* method send their standard error to this destination. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
803 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
804 |
* <p>If the destination is {@link Redirect#PIPE Redirect.PIPE} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
805 |
* (the initial value), then the error output of a subprocess |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
806 |
* can be read using the input stream returned by {@link |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
807 |
* Process#getErrorStream()}. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
808 |
* If the destination is set to any other value, then |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
809 |
* {@link Process#getErrorStream()} will return a |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
810 |
* <a href="#redirect-output">null input stream</a>. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
811 |
* |
28058
87940c838900
8056238: (process) ProcessBuilder.redirectError spec has a broken link
rriggs
parents:
25859
diff
changeset
|
812 |
* <p>If the {@link #redirectErrorStream() redirectErrorStream} |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
813 |
* attribute has been set {@code true}, then the redirection set |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
814 |
* by this method has no effect. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
815 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
816 |
* @param destination the new standard error destination |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
817 |
* @return this process builder |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
818 |
* @throws IllegalArgumentException |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
819 |
* if the redirect does not correspond to a valid |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
820 |
* destination of data, that is, has type |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
821 |
* {@link Redirect.Type#READ READ} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
822 |
* @since 1.7 |
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 |
public ProcessBuilder redirectError(Redirect destination) { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
825 |
if (destination.type() == Redirect.Type.READ) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
826 |
throw new IllegalArgumentException( |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
827 |
"Redirect invalid for writing: " + destination); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
828 |
redirects()[2] = destination; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
829 |
return this; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
830 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
831 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
832 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
833 |
* Sets this process builder's standard input source to a file. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
834 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
835 |
* <p>This is a convenience method. An invocation of the form |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
836 |
* {@code redirectInput(file)} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
837 |
* behaves in exactly the same way as the invocation |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
838 |
* {@link #redirectInput(Redirect) redirectInput} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
839 |
* {@code (Redirect.from(file))}. |
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 |
* @param file the new standard input source |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
842 |
* @return this process builder |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
843 |
* @since 1.7 |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
844 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
845 |
public ProcessBuilder redirectInput(File file) { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
846 |
return redirectInput(Redirect.from(file)); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
847 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
848 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
849 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
850 |
* Sets this process builder's standard output destination to a file. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
851 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
852 |
* <p>This is a convenience method. An invocation of the form |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
853 |
* {@code redirectOutput(file)} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
854 |
* behaves in exactly the same way as the invocation |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
855 |
* {@link #redirectOutput(Redirect) redirectOutput} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
856 |
* {@code (Redirect.to(file))}. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
857 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
858 |
* @param file the new standard output destination |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
859 |
* @return this process builder |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
860 |
* @since 1.7 |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
861 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
862 |
public ProcessBuilder redirectOutput(File file) { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
863 |
return redirectOutput(Redirect.to(file)); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
864 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
865 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
866 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
867 |
* Sets this process builder's standard error destination to a file. |
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 |
* <p>This is a convenience method. An invocation of the form |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
870 |
* {@code redirectError(file)} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
871 |
* behaves in exactly the same way as the invocation |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
872 |
* {@link #redirectError(Redirect) redirectError} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
873 |
* {@code (Redirect.to(file))}. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
874 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
875 |
* @param file the new standard error destination |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
876 |
* @return this process builder |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
877 |
* @since 1.7 |
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 |
public ProcessBuilder redirectError(File file) { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
880 |
return redirectError(Redirect.to(file)); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
881 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
882 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
883 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
884 |
* Returns this process builder's standard input source. |
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 |
* Subprocesses subsequently started by this object's {@link #start()} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
887 |
* method obtain their standard input from this source. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
888 |
* The initial value is {@link Redirect#PIPE Redirect.PIPE}. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
889 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
890 |
* @return this process builder's standard input source |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
891 |
* @since 1.7 |
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 |
public Redirect redirectInput() { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
894 |
return (redirects == null) ? Redirect.PIPE : redirects[0]; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
895 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
896 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
897 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
898 |
* Returns this process builder's standard output destination. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
899 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
900 |
* Subprocesses subsequently started by this object's {@link #start()} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
901 |
* method redirect their standard output to this destination. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
902 |
* The initial value is {@link Redirect#PIPE Redirect.PIPE}. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
903 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
904 |
* @return this process builder's standard output destination |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
905 |
* @since 1.7 |
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 |
public Redirect redirectOutput() { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
908 |
return (redirects == null) ? Redirect.PIPE : redirects[1]; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
909 |
} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
910 |
|
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
911 |
/** |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
912 |
* Returns this process builder's standard error destination. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
913 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
914 |
* Subprocesses subsequently started by this object's {@link #start()} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
915 |
* method redirect their standard error to this destination. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
916 |
* The initial value is {@link Redirect#PIPE Redirect.PIPE}. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
917 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
918 |
* @return this process builder's standard error destination |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
919 |
* @since 1.7 |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
920 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
921 |
public Redirect redirectError() { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
922 |
return (redirects == null) ? Redirect.PIPE : redirects[2]; |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
923 |
} |
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 |
* Sets the source and destination for subprocess standard I/O |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
927 |
* to be the same as those of the current Java process. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
928 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
929 |
* <p>This is a convenience method. An invocation of the form |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
930 |
* <pre> {@code |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
931 |
* pb.inheritIO() |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
932 |
* }</pre> |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
933 |
* behaves in exactly the same way as the invocation |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
934 |
* <pre> {@code |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
935 |
* pb.redirectInput(Redirect.INHERIT) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
936 |
* .redirectOutput(Redirect.INHERIT) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
937 |
* .redirectError(Redirect.INHERIT) |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
938 |
* }</pre> |
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 |
* This gives behavior equivalent to most operating system |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
941 |
* command interpreters, or the standard C library function |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
942 |
* {@code system()}. |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
943 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
944 |
* @return this process builder |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
945 |
* @since 1.7 |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
946 |
*/ |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
947 |
public ProcessBuilder inheritIO() { |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
948 |
Arrays.fill(redirects(), Redirect.INHERIT); |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
949 |
return this; |
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 |
|
2 | 952 |
/** |
953 |
* Tells whether this process builder merges standard error and |
|
954 |
* standard output. |
|
955 |
* |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
956 |
* <p>If this property is {@code true}, then any error output |
2 | 957 |
* generated by subprocesses subsequently started by this object's |
958 |
* {@link #start()} method will be merged with the standard |
|
959 |
* output, so that both can be read using the |
|
960 |
* {@link Process#getInputStream()} method. This makes it easier |
|
961 |
* to correlate error messages with the corresponding output. |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
962 |
* The initial value is {@code false}. |
2 | 963 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
964 |
* @return this process builder's {@code redirectErrorStream} property |
2 | 965 |
*/ |
966 |
public boolean redirectErrorStream() { |
|
967 |
return redirectErrorStream; |
|
968 |
} |
|
969 |
||
970 |
/** |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
971 |
* Sets this process builder's {@code redirectErrorStream} property. |
2 | 972 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
973 |
* <p>If this property is {@code true}, then any error output |
2 | 974 |
* generated by subprocesses subsequently started by this object's |
975 |
* {@link #start()} method will be merged with the standard |
|
976 |
* output, so that both can be read using the |
|
977 |
* {@link Process#getInputStream()} method. This makes it easier |
|
978 |
* to correlate error messages with the corresponding output. |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
979 |
* The initial value is {@code false}. |
2 | 980 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
981 |
* @param redirectErrorStream the new property value |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
982 |
* @return this process builder |
2 | 983 |
*/ |
984 |
public ProcessBuilder redirectErrorStream(boolean redirectErrorStream) { |
|
985 |
this.redirectErrorStream = redirectErrorStream; |
|
986 |
return this; |
|
987 |
} |
|
988 |
||
989 |
/** |
|
990 |
* Starts a new process using the attributes of this process builder. |
|
991 |
* |
|
992 |
* <p>The new process will |
|
993 |
* invoke the command and arguments given by {@link #command()}, |
|
994 |
* in a working directory as given by {@link #directory()}, |
|
995 |
* with a process environment as given by {@link #environment()}. |
|
996 |
* |
|
997 |
* <p>This method checks that the command is a valid operating |
|
998 |
* system command. Which commands are valid is system-dependent, |
|
999 |
* but at the very least the command must be a non-empty list of |
|
1000 |
* non-null strings. |
|
1001 |
* |
|
9500
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
7816
diff
changeset
|
1002 |
* <p>A minimal set of system dependent environment variables may |
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
7816
diff
changeset
|
1003 |
* be required to start a process on some operating systems. |
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
7816
diff
changeset
|
1004 |
* As a result, the subprocess may inherit additional environment variable |
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
7816
diff
changeset
|
1005 |
* settings beyond those in the process builder's {@link #environment()}. |
268f823d9e1c
7034570: java.lang.Runtime.exec(String[] cmd, String[] env) can not work properly if SystemRoot not inherited
michaelm
parents:
7816
diff
changeset
|
1006 |
* |
2 | 1007 |
* <p>If there is a security manager, its |
1008 |
* {@link SecurityManager#checkExec checkExec} |
|
1009 |
* method is called with the first component of this object's |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1010 |
* {@code command} array as its argument. This may result in |
2 | 1011 |
* a {@link SecurityException} being thrown. |
1012 |
* |
|
1013 |
* <p>Starting an operating system process is highly system-dependent. |
|
1014 |
* Among the many things that can go wrong are: |
|
1015 |
* <ul> |
|
1016 |
* <li>The operating system program file was not found. |
|
1017 |
* <li>Access to the program file was denied. |
|
1018 |
* <li>The working directory does not exist. |
|
25539
9d290547d266
8036571: (process) Process process arguments carefully
rriggs
parents:
23010
diff
changeset
|
1019 |
* <li>Invalid character in command argument, such as NUL. |
2 | 1020 |
* </ul> |
1021 |
* |
|
1022 |
* <p>In such cases an exception will be thrown. The exact nature |
|
1023 |
* of the exception is system-dependent, but it will always be a |
|
1024 |
* subclass of {@link IOException}. |
|
1025 |
* |
|
28872
82a09f5a7ed6
8072034: (process) ProcessBuilder.start and Runtime.exec UnsupportedOperationException editorial cleanup
rriggs
parents:
28750
diff
changeset
|
1026 |
* <p>If the operating system does not support the creation of |
82a09f5a7ed6
8072034: (process) ProcessBuilder.start and Runtime.exec UnsupportedOperationException editorial cleanup
rriggs
parents:
28750
diff
changeset
|
1027 |
* processes, an {@link UnsupportedOperationException} will be thrown. |
82a09f5a7ed6
8072034: (process) ProcessBuilder.start and Runtime.exec UnsupportedOperationException editorial cleanup
rriggs
parents:
28750
diff
changeset
|
1028 |
* |
2 | 1029 |
* <p>Subsequent modifications to this process builder will not |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1030 |
* affect the returned {@link Process}. |
2 | 1031 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1032 |
* @return a new {@link Process} object for managing the subprocess |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1033 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1034 |
* @throws NullPointerException |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1035 |
* if an element of the command list is null |
2 | 1036 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1037 |
* @throws IndexOutOfBoundsException |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1038 |
* if the command is an empty list (has size {@code 0}) |
2 | 1039 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1040 |
* @throws SecurityException |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1041 |
* if a security manager exists and |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1042 |
* <ul> |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1043 |
* |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1044 |
* <li>its |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1045 |
* {@link SecurityManager#checkExec checkExec} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1046 |
* method doesn't allow creation of the subprocess, or |
2 | 1047 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1048 |
* <li>the standard input to the subprocess was |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1049 |
* {@linkplain #redirectInput redirected from a file} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1050 |
* and the security manager's |
29600
3c042ba9fd42
8071480: (process spec) ProcessBuilder.start spec linked to the wrong checkRead and checkWrite methods
rriggs
parents:
29381
diff
changeset
|
1051 |
* {@link SecurityManager#checkRead(String) checkRead} method |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1052 |
* denies read access to the file, or |
2 | 1053 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1054 |
* <li>the standard output or standard error of the |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1055 |
* subprocess was |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1056 |
* {@linkplain #redirectOutput redirected to a file} |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1057 |
* and the security manager's |
29600
3c042ba9fd42
8071480: (process spec) ProcessBuilder.start spec linked to the wrong checkRead and checkWrite methods
rriggs
parents:
29381
diff
changeset
|
1058 |
* {@link SecurityManager#checkWrite(String) checkWrite} method |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1059 |
* denies write access to the file |
2 | 1060 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1061 |
* </ul> |
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1062 |
* |
28750
a1dae439cdab
8055330: (process spec) ProcessBuilder.start and Runtime.exec should throw UnsupportedOperationException on platforms that don't support
rriggs
parents:
28058
diff
changeset
|
1063 |
* @throws UnsupportedOperationException |
a1dae439cdab
8055330: (process spec) ProcessBuilder.start and Runtime.exec should throw UnsupportedOperationException on platforms that don't support
rriggs
parents:
28058
diff
changeset
|
1064 |
* If the operating system does not support the creation of processes. |
a1dae439cdab
8055330: (process spec) ProcessBuilder.start and Runtime.exec should throw UnsupportedOperationException on platforms that don't support
rriggs
parents:
28058
diff
changeset
|
1065 |
* |
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1066 |
* @throws IOException if an I/O error occurs |
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 |
* @see Runtime#exec(String[], String[], java.io.File) |
2 | 1069 |
*/ |
1070 |
public Process start() throws IOException { |
|
33826
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1071 |
return start(redirects); |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1072 |
} |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1073 |
|
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1074 |
/** |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1075 |
* Start a new Process using an explicit array of redirects. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1076 |
* See {@link #start} for details of starting each Process. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1077 |
* |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1078 |
* @param redirect array of redirects for stdin, stdout, stderr |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1079 |
* @return the new Process |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1080 |
* @throws IOException if an I/O error occurs |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1081 |
*/ |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1082 |
private Process start(Redirect[] redirects) throws IOException { |
2 | 1083 |
// Must convert to array first -- a malicious user-supplied |
1084 |
// list might try to circumvent the security check. |
|
1085 |
String[] cmdarray = command.toArray(new String[command.size()]); |
|
5186
1bbb82130b38
6910590: Application can modify command array, in ProcessBuilder
michaelm
parents:
48
diff
changeset
|
1086 |
cmdarray = cmdarray.clone(); |
1bbb82130b38
6910590: Application can modify command array, in ProcessBuilder
michaelm
parents:
48
diff
changeset
|
1087 |
|
2 | 1088 |
for (String arg : cmdarray) |
1089 |
if (arg == null) |
|
1090 |
throw new NullPointerException(); |
|
1091 |
// Throws IndexOutOfBoundsException if command is empty |
|
1092 |
String prog = cmdarray[0]; |
|
1093 |
||
1094 |
SecurityManager security = System.getSecurityManager(); |
|
1095 |
if (security != null) |
|
1096 |
security.checkExec(prog); |
|
1097 |
||
1098 |
String dir = directory == null ? null : directory.toString(); |
|
1099 |
||
25539
9d290547d266
8036571: (process) Process process arguments carefully
rriggs
parents:
23010
diff
changeset
|
1100 |
for (int i = 1; i < cmdarray.length; i++) { |
9d290547d266
8036571: (process) Process process arguments carefully
rriggs
parents:
23010
diff
changeset
|
1101 |
if (cmdarray[i].indexOf('\u0000') >= 0) { |
9d290547d266
8036571: (process) Process process arguments carefully
rriggs
parents:
23010
diff
changeset
|
1102 |
throw new IOException("invalid null character in command"); |
9d290547d266
8036571: (process) Process process arguments carefully
rriggs
parents:
23010
diff
changeset
|
1103 |
} |
9d290547d266
8036571: (process) Process process arguments carefully
rriggs
parents:
23010
diff
changeset
|
1104 |
} |
9d290547d266
8036571: (process) Process process arguments carefully
rriggs
parents:
23010
diff
changeset
|
1105 |
|
2 | 1106 |
try { |
1107 |
return ProcessImpl.start(cmdarray, |
|
1108 |
environment, |
|
1109 |
dir, |
|
48
dc5744ca15ea
4960438: (process) Need IO redirection API for subprocesses
martin
parents:
2
diff
changeset
|
1110 |
redirects, |
2 | 1111 |
redirectErrorStream); |
17467
374c1cceefff
8012453: (process) Runtime.exec(String) fails if command contains spaces [win]
uta
parents:
16877
diff
changeset
|
1112 |
} catch (IOException | IllegalArgumentException e) { |
16877 | 1113 |
String exceptionInfo = ": " + e.getMessage(); |
1114 |
Throwable cause = e; |
|
17467
374c1cceefff
8012453: (process) Runtime.exec(String) fails if command contains spaces [win]
uta
parents:
16877
diff
changeset
|
1115 |
if ((e instanceof IOException) && security != null) { |
16877 | 1116 |
// Can not disclose the fail reason for read-protected files. |
1117 |
try { |
|
1118 |
security.checkRead(prog); |
|
19606
6c846d61ba2f
8023717: (process) ProcessBuilder should catch SecurityException rather than AccessControlException
alanb
parents:
18776
diff
changeset
|
1119 |
} catch (SecurityException se) { |
16877 | 1120 |
exceptionInfo = ""; |
19606
6c846d61ba2f
8023717: (process) ProcessBuilder should catch SecurityException rather than AccessControlException
alanb
parents:
18776
diff
changeset
|
1121 |
cause = se; |
16877 | 1122 |
} |
1123 |
} |
|
2 | 1124 |
// It's much easier for us to create a high-quality error |
1125 |
// message than the low-level C code which found the problem. |
|
1126 |
throw new IOException( |
|
1127 |
"Cannot run program \"" + prog + "\"" |
|
1128 |
+ (dir == null ? "" : " (in directory \"" + dir + "\")") |
|
16877 | 1129 |
+ exceptionInfo, |
1130 |
cause); |
|
2 | 1131 |
} |
1132 |
} |
|
33826
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1133 |
|
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1134 |
/** |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1135 |
* Starts a Process for each ProcessBuilder, creating a pipeline of |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1136 |
* processes linked by their standard output and standard input streams. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1137 |
* The attributes of each ProcessBuilder are used to start the respective |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1138 |
* process except that as each process is started, its standard output |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1139 |
* is directed to the standard input of the next. The redirects for standard |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1140 |
* input of the first process and standard output of the last process are |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1141 |
* initialized using the redirect settings of the respective ProcessBuilder. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1142 |
* All other {@code ProcessBuilder} redirects should be |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1143 |
* {@link Redirect#PIPE Redirect.PIPE}. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1144 |
* <p> |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1145 |
* All input and output streams between the intermediate processes are |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1146 |
* not accessible. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1147 |
* The {@link Process#getOutputStream standard input} of all processes |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1148 |
* except the first process are <i>null output streams</i> |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1149 |
* The {@link Process#getInputStream standard output} of all processes |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1150 |
* except the last process are <i>null input streams</i>. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1151 |
* <p> |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1152 |
* The {@link #redirectErrorStream} of each ProcessBuilder applies to the |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1153 |
* respective process. If set to {@code true}, the error stream is written |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1154 |
* to the same stream as standard output. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1155 |
* <p> |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1156 |
* If starting any of the processes throws an Exception, all processes |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1157 |
* are forcibly destroyed. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1158 |
* <p> |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1159 |
* The {@code startPipeline} method performs the same checks on |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1160 |
* each ProcessBuilder as does the {@link #start} method. The new process |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1161 |
* will invoke the command and arguments given by {@link #command()}, |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1162 |
* in a working directory as given by {@link #directory()}, |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1163 |
* with a process environment as given by {@link #environment()}. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1164 |
* <p> |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1165 |
* This method checks that the command is a valid operating |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1166 |
* system command. Which commands are valid is system-dependent, |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1167 |
* but at the very least the command must be a non-empty list of |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1168 |
* non-null strings. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1169 |
* <p> |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1170 |
* A minimal set of system dependent environment variables may |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1171 |
* be required to start a process on some operating systems. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1172 |
* As a result, the subprocess may inherit additional environment variable |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1173 |
* settings beyond those in the process builder's {@link #environment()}. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1174 |
* <p> |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1175 |
* If there is a security manager, its |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1176 |
* {@link SecurityManager#checkExec checkExec} |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1177 |
* method is called with the first component of this object's |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1178 |
* {@code command} array as its argument. This may result in |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1179 |
* a {@link SecurityException} being thrown. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1180 |
* <p> |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1181 |
* Starting an operating system process is highly system-dependent. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1182 |
* Among the many things that can go wrong are: |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1183 |
* <ul> |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1184 |
* <li>The operating system program file was not found. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1185 |
* <li>Access to the program file was denied. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1186 |
* <li>The working directory does not exist. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1187 |
* <li>Invalid character in command argument, such as NUL. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1188 |
* </ul> |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1189 |
* <p> |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1190 |
* In such cases an exception will be thrown. The exact nature |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1191 |
* of the exception is system-dependent, but it will always be a |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1192 |
* subclass of {@link IOException}. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1193 |
* <p> |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1194 |
* If the operating system does not support the creation of |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1195 |
* processes, an {@link UnsupportedOperationException} will be thrown. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1196 |
* <p> |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1197 |
* Subsequent modifications to this process builder will not |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1198 |
* affect the returned {@link Process}. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1199 |
* @apiNote |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1200 |
* For example to count the unique imports for all the files in a file hierarchy |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1201 |
* on a Unix compatible platform: |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1202 |
* <pre>{@code |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1203 |
* String directory = "/home/duke/src"; |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1204 |
* ProcessBuilder[] builders = { |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1205 |
* new ProcessBuilder("find", directory, "-type", "f"), |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1206 |
new ProcessBuilder("xargs", "grep", "-h", "^import "), |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1207 |
new ProcessBuilder("awk", "{print $2;}"), |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1208 |
new ProcessBuilder("sort", "-u")}; |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1209 |
* List<Process> processes = ProcessBuilder.startPipeline( |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1210 |
* Arrays.asList(builders)); |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1211 |
* Process last = processes.get(processes.size()-1); |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1212 |
* try (InputStream is = last.getInputStream(); |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1213 |
* Reader isr = new InputStreamReader(is); |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1214 |
* BufferedReader r = new BufferedReader(isr)) { |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1215 |
* long count = r.lines().count(); |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1216 |
* } |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1217 |
* }</pre> |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1218 |
* |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1219 |
* @param builders a List of ProcessBuilders |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1220 |
* @return a {@code List<Process>}es started from the corresponding |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1221 |
* ProcessBuilder |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1222 |
* @throws IllegalArgumentException any of the redirects except the |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1223 |
* standard input of the first builder and the standard output of |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1224 |
* the last builder are not {@link Redirect#PIPE}. |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1225 |
* @throws NullPointerException |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1226 |
* if an element of the command list is null or |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1227 |
* if an element of the ProcessBuilder list is null or |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1228 |
* the builders argument is null |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1229 |
* @throws IndexOutOfBoundsException |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1230 |
* if the command is an empty list (has size {@code 0}) |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1231 |
* @throws SecurityException |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1232 |
* if a security manager exists and |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1233 |
* <ul> |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1234 |
* <li>its |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1235 |
* {@link SecurityManager#checkExec checkExec} |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1236 |
* method doesn't allow creation of the subprocess, or |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1237 |
* <li>the standard input to the subprocess was |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1238 |
* {@linkplain #redirectInput redirected from a file} |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1239 |
* and the security manager's |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1240 |
* {@link SecurityManager#checkRead(String) checkRead} method |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1241 |
* denies read access to the file, or |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1242 |
* <li>the standard output or standard error of the |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1243 |
* subprocess was |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1244 |
* {@linkplain #redirectOutput redirected to a file} |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1245 |
* and the security manager's |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1246 |
* {@link SecurityManager#checkWrite(String) checkWrite} method |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1247 |
* denies write access to the file |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1248 |
* </ul> |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1249 |
* |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1250 |
* @throws UnsupportedOperationException |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1251 |
* If the operating system does not support the creation of processes |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1252 |
* |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1253 |
* @throws IOException if an I/O error occurs |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1254 |
*/ |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1255 |
public static List<Process> startPipeline(List<ProcessBuilder> builders) throws IOException { |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1256 |
// Accumulate and check the builders |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1257 |
final int numBuilders = builders.size(); |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1258 |
List<Process> processes = new ArrayList<>(numBuilders); |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1259 |
try { |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1260 |
Redirect prevOutput = null; |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1261 |
for (int index = 0; index < builders.size(); index++) { |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1262 |
ProcessBuilder builder = builders.get(index); |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1263 |
Redirect[] redirects = builder.redirects(); |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1264 |
if (index > 0) { |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1265 |
// check the current Builder to see if it can take input from the previous |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1266 |
if (builder.redirectInput() != Redirect.PIPE) { |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1267 |
throw new IllegalArgumentException("builder redirectInput()" + |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1268 |
" must be PIPE except for the first builder: " |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1269 |
+ builder.redirectInput()); |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1270 |
} |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1271 |
redirects[0] = prevOutput; |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1272 |
} |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1273 |
if (index < numBuilders - 1) { |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1274 |
// check all but the last stage has output = PIPE |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1275 |
if (builder.redirectOutput() != Redirect.PIPE) { |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1276 |
throw new IllegalArgumentException("builder redirectOutput()" + |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1277 |
" must be PIPE except for the last builder: " |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1278 |
+ builder.redirectOutput()); |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1279 |
} |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1280 |
redirects[1] = new RedirectPipeImpl(); // placeholder for new output |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1281 |
} |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1282 |
processes.add(builder.start(redirects)); |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1283 |
prevOutput = redirects[1]; |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1284 |
} |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1285 |
} catch (Exception ex) { |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1286 |
// Cleanup processes already started |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1287 |
processes.forEach(Process::destroyForcibly); |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1288 |
processes.forEach(p -> { |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1289 |
try { |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1290 |
p.waitFor(); // Wait for it to exit |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1291 |
} catch (InterruptedException ie) { |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1292 |
// If interrupted; continue with next Process |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1293 |
Thread.currentThread().interrupt(); |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1294 |
} |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1295 |
}); |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1296 |
throw ex; |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1297 |
} |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1298 |
return processes; |
a9e5f1b8ea57
8132394: (process) ProcessBuilder support for a pipeline of processes
rriggs
parents:
32763
diff
changeset
|
1299 |
} |
2 | 1300 |
} |