Skip to content

Commit

Permalink
Include ProcessEnvironment and UNIXProcess from solaris implementatio…
Browse files Browse the repository at this point in the history
…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
wasabii committed Feb 26, 2024
1 parent feb5908 commit 2d2b34e
Show file tree
Hide file tree
Showing 14 changed files with 954 additions and 161 deletions.
1 change: 1 addition & 0 deletions openjdk.props
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,7 @@
<OpenJdkSource Remove="$(OpenJdkDir)\jdk\src\share\classes\java\lang\Thread.java" />
<OpenJdkSource Include="$(OpenJdkDir)\jdk\src\windows\classes\java\lang\Terminator.java" />
<OpenJdkSource Include="$(OpenJdkDir)\jdk\src\windows\classes\java\lang\ProcessEnvironment.java" />
<OpenJdkSource Include="$(OpenJdkDir)\jdk\src\solaris\classes\java\lang\UNIXProcess.java" />
<OpenJdkSource Include="$(OpenJdkDir)\jdk\src\share\classes\java\lang\invoke\**\*.java" PackagePath="java\lang\invoke" />
<OpenJdkSource Remove="$(OpenJdkDir)\jdk\src\share\classes\java\lang\invoke\DirectMethodHandle.java" />
<OpenJdkSource Include="$(OpenJdkDir)\jdk\src\share\classes\java\lang\annotation\**\*.java" PackagePath="java\lang\annotation" />
Expand Down
4 changes: 2 additions & 2 deletions src/IKVM.Java/local/java/io/FileDescriptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ public final class FileDescriptor {
sun.misc.SharedSecrets.setJavaIOFileDescriptorAccess(
new sun.misc.JavaIOFileDescriptorAccess() {
public void set(FileDescriptor obj, int fd) {

obj.fd = fd;
}

public int get(FileDescriptor obj) {
return obj.fd;
}

public void setHandle(FileDescriptor obj, long handle) {

obj.handle = handle;
}

public long getHandle(FileDescriptor obj) {
Expand Down
178 changes: 144 additions & 34 deletions src/IKVM.Java/local/java/lang/ProcessImpl.java
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(); }
}
}

}
}
}
Loading

0 comments on commit 2d2b34e

Please sign in to comment.