-
-
Notifications
You must be signed in to change notification settings - Fork 126
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Include ProcessEnvironment and UNIXProcess from solaris implementatio…
…n and redirect through ProcessImpl. Executing processes on Linux/OSX should thus go through OpenJDK native fork/exec code. Which might work with the pipe redirects? Also might fail because fork/exec doesn't work. We shall see.
- Loading branch information
Showing
14 changed files
with
954 additions
and
161 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,46 +1,156 @@ | ||
/* | ||
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. | ||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
* | ||
* This code is free software; you can redistribute it and/or modify it | ||
* under the terms of the GNU General Public License version 2 only, as | ||
* published by the Free Software Foundation. Oracle designates this | ||
* particular file as subject to the "Classpath" exception as provided | ||
* by Oracle in the LICENSE file that accompanied this code. | ||
* | ||
* This code is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
* version 2 for more details (a copy is included in the LICENSE file that | ||
* accompanied this code). | ||
* | ||
* You should have received a copy of the GNU General Public License version | ||
* 2 along with this work; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
* | ||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
* or visit www.oracle.com if you need additional information or have any | ||
* questions. | ||
*/ | ||
|
||
package java.lang; | ||
|
||
import java.io.*; | ||
import java.io.IOException; | ||
import java.io.FileInputStream; | ||
import java.io.FileOutputStream; | ||
import java.lang.ProcessBuilder.Redirect; | ||
import java.util.*; | ||
|
||
final class ProcessImpl extends Process { | ||
/** | ||
* This class is for the exclusive use of ProcessBuilder.start() to | ||
* create new processes. | ||
* | ||
* @author Martin Buchholz | ||
* @since 1.5 | ||
*/ | ||
final class ProcessImpl { | ||
|
||
public native void dummy(); | ||
|
||
cli.System.Diagnostics.Process process; | ||
OutputStream outputStream; | ||
InputStream inputStream; | ||
InputStream errorStream; | ||
private static final sun.misc.JavaIOFileDescriptorAccess fdAccess | ||
= sun.misc.SharedSecrets.getJavaIOFileDescriptorAccess(); | ||
|
||
static native Process start(String cmdarray[], java.util.Map<String, String> environment, String dir, ProcessBuilder.Redirect[] redirects, boolean redirectErrorStream) throws IOException; | ||
private ProcessImpl() {} // Not instantiable | ||
|
||
private ProcessImpl(cli.System.Diagnostics.Process process, OutputStream outputStream, InputStream inputStream, InputStream errorStream) { | ||
this.process = process; | ||
this.outputStream = outputStream; | ||
this.inputStream = inputStream; | ||
this.errorStream = errorStream; | ||
private static byte[] toCString(String s) { | ||
if (s == null) | ||
return null; | ||
byte[] bytes = s.getBytes(); | ||
byte[] result = new byte[bytes.length + 1]; | ||
System.arraycopy(bytes, 0, | ||
result, 0, | ||
bytes.length); | ||
result[result.length-1] = (byte)0; | ||
return result; | ||
} | ||
|
||
@Override | ||
public OutputStream getOutputStream() { | ||
return outputStream; | ||
} | ||
// Only for use by ProcessBuilder.start() | ||
static Process start(String[] cmdarray, | ||
java.util.Map<String,String> environment, | ||
String dir, | ||
ProcessBuilder.Redirect[] redirects, | ||
boolean redirectErrorStream) | ||
throws IOException | ||
{ | ||
if (cli.IKVM.Runtime.RuntimeUtil.get_IsWindows()) { | ||
return Win32Process.start(cmdarray, environment, dir, redirects, redirectErrorStream); | ||
} else { | ||
|
||
@Override | ||
public InputStream getInputStream() { | ||
return inputStream; | ||
} | ||
|
||
@Override | ||
public InputStream getErrorStream() { | ||
return errorStream; | ||
} | ||
|
||
@Override | ||
public native int waitFor() throws InterruptedException; | ||
|
||
@Override | ||
public native int exitValue(); | ||
|
||
@Override | ||
public native void destroy(); | ||
assert cmdarray != null && cmdarray.length > 0; | ||
|
||
// Convert arguments to a contiguous block; it's easier to do | ||
// memory management in Java than in C. | ||
byte[][] args = new byte[cmdarray.length-1][]; | ||
int size = args.length; // For added NUL bytes | ||
for (int i = 0; i < args.length; i++) { | ||
args[i] = cmdarray[i+1].getBytes(); | ||
size += args[i].length; | ||
} | ||
byte[] argBlock = new byte[size]; | ||
int i = 0; | ||
for (byte[] arg : args) { | ||
System.arraycopy(arg, 0, argBlock, i, arg.length); | ||
i += arg.length + 1; | ||
// No need to write NUL bytes explicitly | ||
} | ||
|
||
int[] envc = new int[1]; | ||
byte[] envBlock = UNIXProcessEnvironment.toEnvironmentBlock(environment, envc); | ||
|
||
int[] std_fds; | ||
|
||
FileInputStream f0 = null; | ||
FileOutputStream f1 = null; | ||
FileOutputStream f2 = null; | ||
|
||
try { | ||
if (redirects == null) { | ||
std_fds = new int[] { -1, -1, -1 }; | ||
} else { | ||
std_fds = new int[3]; | ||
|
||
if (redirects[0] == Redirect.PIPE) | ||
std_fds[0] = -1; | ||
else if (redirects[0] == Redirect.INHERIT) | ||
std_fds[0] = 0; | ||
else { | ||
f0 = new FileInputStream(redirects[0].file()); | ||
std_fds[0] = fdAccess.get(f0.getFD()); | ||
} | ||
|
||
if (redirects[1] == Redirect.PIPE) | ||
std_fds[1] = -1; | ||
else if (redirects[1] == Redirect.INHERIT) | ||
std_fds[1] = 1; | ||
else { | ||
f1 = new FileOutputStream(redirects[1].file(), | ||
redirects[1].append()); | ||
std_fds[1] = fdAccess.get(f1.getFD()); | ||
} | ||
|
||
if (redirects[2] == Redirect.PIPE) | ||
std_fds[2] = -1; | ||
else if (redirects[2] == Redirect.INHERIT) | ||
std_fds[2] = 2; | ||
else { | ||
f2 = new FileOutputStream(redirects[2].file(), | ||
redirects[2].append()); | ||
std_fds[2] = fdAccess.get(f2.getFD()); | ||
} | ||
} | ||
|
||
return new UNIXProcess | ||
(toCString(cmdarray[0]), | ||
argBlock, args.length, | ||
envBlock, envc[0], | ||
toCString(dir), | ||
std_fds, | ||
redirectErrorStream); | ||
} finally { | ||
// In theory, close() can throw IOException | ||
// (although it is rather unlikely to happen here) | ||
try { if (f0 != null) f0.close(); } | ||
finally { | ||
try { if (f1 != null) f1.close(); } | ||
finally { if (f2 != null) f2.close(); } | ||
} | ||
} | ||
|
||
} | ||
} | ||
} |
Oops, something went wrong.