You've already forked linux-packaging-mono
Imported Upstream version 3.10.0
Former-commit-id: 172c8e3c300b39d5785c7a3e8dfb08ebdbc1a99b
This commit is contained in:
@ -1 +1 @@
|
||||
bbc1d241f632078e8ecf146e9398406c5719dd2f
|
||||
07fd7bd567e5b0ae8b3ae9c32741b56f6f363b0a
|
88
external/ikvm/openjdk/java/lang/LangHelper.java
vendored
88
external/ikvm/openjdk/java/lang/LangHelper.java
vendored
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (C) 2007-2011 Jeroen Frijters
|
||||
Copyright (C) 2007-2014 Jeroen Frijters
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@ -24,80 +24,40 @@
|
||||
|
||||
package java.lang;
|
||||
|
||||
import ikvm.runtime.AssemblyClassLoader;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.security.AccessController;
|
||||
import java.util.Enumeration;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Executable;
|
||||
import java.security.AccessControlContext;
|
||||
import java.util.Map;
|
||||
import sun.nio.ch.Interruptible;
|
||||
import sun.reflect.annotation.AnnotationType;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
|
||||
@ikvm.lang.Internal
|
||||
public class LangHelper
|
||||
{
|
||||
private static boolean addedSystemPackages;
|
||||
|
||||
private static void addSystemPackage(Map pkgMap)
|
||||
{
|
||||
// NOTE caller must have acquired lock on pkgMap
|
||||
if (!addedSystemPackages)
|
||||
{
|
||||
addedSystemPackages = true;
|
||||
String[] pkgs = getBootClassPackages();
|
||||
for (int i = 0; i < pkgs.length; i++)
|
||||
{
|
||||
pkgMap.put(pkgs[i],
|
||||
new Package(pkgs[i],
|
||||
VMSystemProperties.SPEC_TITLE, // specTitle
|
||||
VMSystemProperties.SPEC_VERSION, // specVersion
|
||||
VMSystemProperties.SPEC_VENDOR, // specVendor
|
||||
"IKVM.NET OpenJDK", // implTitle
|
||||
PropertyConstants.openjdk_version, // implVersion
|
||||
"Oracle Corporation & others", // implVendor
|
||||
null, // sealBase
|
||||
null)); // class loader
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static native String[] getBootClassPackages();
|
||||
|
||||
/* this method gets called by Package.getSystemPackage() via a redefined method in map.xml */
|
||||
static Package getSystemPackage(Map pkgs, String name)
|
||||
{
|
||||
synchronized (pkgs)
|
||||
{
|
||||
addSystemPackage(pkgs);
|
||||
return (Package)pkgs.get(name);
|
||||
}
|
||||
}
|
||||
|
||||
/* this method gets called by Package.getSystemPackages() via a redefined method in map.xml */
|
||||
static Package[] getSystemPackages(Map pkgs)
|
||||
{
|
||||
synchronized (pkgs)
|
||||
{
|
||||
addSystemPackage(pkgs);
|
||||
return (Package[])pkgs.values().toArray(new Package[pkgs.size()]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static sun.misc.JavaLangAccess getJavaLangAccess()
|
||||
{
|
||||
return new sun.misc.JavaLangAccess() {
|
||||
public sun.reflect.ConstantPool getConstantPool(Class klass) {
|
||||
return null;
|
||||
return klass.getConstantPool();
|
||||
}
|
||||
public void setAnnotationType(Class klass, AnnotationType type) {
|
||||
klass.setAnnotationType(type);
|
||||
public boolean casAnnotationType(Class<?> klass, AnnotationType oldType, AnnotationType newType) {
|
||||
return klass.casAnnotationType(oldType, newType);
|
||||
}
|
||||
public AnnotationType getAnnotationType(Class klass) {
|
||||
return klass.getAnnotationType();
|
||||
}
|
||||
public Map<Class<? extends Annotation>, Annotation> getDeclaredAnnotationMap(Class<?> klass) {
|
||||
return klass.getDeclaredAnnotationMap();
|
||||
}
|
||||
public byte[] getRawClassAnnotations(Class<?> klass) {
|
||||
throw new InternalError();
|
||||
}
|
||||
public byte[] getRawClassTypeAnnotations(Class<?> klass) {
|
||||
return klass.getRawTypeAnnotations();
|
||||
}
|
||||
public byte[] getRawExecutableTypeAnnotations(Executable executable) {
|
||||
return Class.getExecutableTypeAnnotationBytes(executable);
|
||||
}
|
||||
public <E extends Enum<E>>
|
||||
E[] getEnumConstantsShared(Class<E> klass) {
|
||||
return klass.getEnumConstantsShared();
|
||||
@ -114,8 +74,14 @@ public class LangHelper
|
||||
public StackTraceElement getStackTraceElement(Throwable t, int i) {
|
||||
return t.getStackTraceElement(i);
|
||||
}
|
||||
public int getStringHash32(String string) {
|
||||
return StringHelper.hash32(string);
|
||||
public String newStringUnsafe(char[] chars) {
|
||||
return String.valueOf(chars);
|
||||
}
|
||||
public Thread newThreadWithAcc(Runnable target, AccessControlContext acc) {
|
||||
return new Thread(target, acc);
|
||||
}
|
||||
public void invokeFinalize(Object o) throws Throwable {
|
||||
// we don't actually support invoking the finalize method explicitly
|
||||
}
|
||||
};
|
||||
}
|
||||
|
355
external/ikvm/openjdk/java/lang/ProcessImpl.java
vendored
355
external/ikvm/openjdk/java/lang/ProcessImpl.java
vendored
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1995, 2013, 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
|
||||
@ -42,9 +42,15 @@ import java.io.BufferedOutputStream;
|
||||
import java.lang.ProcessBuilder.Redirect;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import cli.System.AsyncCallback;
|
||||
import cli.System.IAsyncResult;
|
||||
import cli.System.Diagnostics.ProcessStartInfo;
|
||||
import cli.System.EventArgs;
|
||||
import cli.System.EventHandler;
|
||||
import cli.System.IO.FileAccess;
|
||||
import cli.System.IO.FileShare;
|
||||
import cli.System.IO.FileMode;
|
||||
@ -146,8 +152,17 @@ final class ProcessImpl extends Process {
|
||||
|
||||
return new ProcessImpl(cmdarray, environment, dir,
|
||||
stdHandles, redirectErrorStream);
|
||||
} catch (Throwable t) {
|
||||
if (f0 != null)
|
||||
f0.close();
|
||||
if (f1 != null)
|
||||
f1.close();
|
||||
if (f2 != null)
|
||||
f2.close();
|
||||
throw t;
|
||||
} finally {
|
||||
// HACK prevent the File[In|Out]putStream objects from closing the streams
|
||||
// (the System.IO.FileStream will eventually be closed explicitly or by its finalizer)
|
||||
if (f0 != null)
|
||||
cli.System.GC.SuppressFinalize(f0);
|
||||
if (f1 != null)
|
||||
@ -158,50 +173,240 @@ final class ProcessImpl extends Process {
|
||||
|
||||
}
|
||||
|
||||
private static class LazyPattern {
|
||||
// Escape-support version:
|
||||
// "(\")((?:\\\\\\1|.)+?)\\1|([^\\s\"]+)";
|
||||
private static final Pattern PATTERN =
|
||||
Pattern.compile("[^\\s\"]+|\"[^\"]*\"");
|
||||
};
|
||||
|
||||
/* Parses the command string parameter into the executable name and
|
||||
* program arguments.
|
||||
*
|
||||
* The command string is broken into tokens. The token separator is a space
|
||||
* or quota character. The space inside quotation is not a token separator.
|
||||
* There are no escape sequences.
|
||||
*/
|
||||
private static String[] getTokensFromCommand(String command) {
|
||||
ArrayList<String> matchList = new ArrayList<>(8);
|
||||
Matcher regexMatcher = LazyPattern.PATTERN.matcher(command);
|
||||
while (regexMatcher.find())
|
||||
matchList.add(regexMatcher.group());
|
||||
return matchList.toArray(new String[matchList.size()]);
|
||||
}
|
||||
|
||||
private static final int VERIFICATION_CMD_BAT = 0;
|
||||
private static final int VERIFICATION_WIN32 = 1;
|
||||
private static final int VERIFICATION_LEGACY = 2;
|
||||
private static final char ESCAPE_VERIFICATION[][] = {
|
||||
// We guarantee the only command file execution for implicit [cmd.exe] run.
|
||||
// http://technet.microsoft.com/en-us/library/bb490954.aspx
|
||||
{' ', '\t', '<', '>', '&', '|', '^'},
|
||||
|
||||
{' ', '\t', '<', '>'},
|
||||
{' ', '\t'}
|
||||
};
|
||||
|
||||
private static String createCommandLine(int verificationType,
|
||||
final String executablePath,
|
||||
final String cmd[])
|
||||
{
|
||||
StringBuilder cmdbuf = new StringBuilder(80);
|
||||
|
||||
cmdbuf.append(executablePath);
|
||||
|
||||
for (int i = 1; i < cmd.length; ++i) {
|
||||
cmdbuf.append(' ');
|
||||
String s = cmd[i];
|
||||
if (needsEscaping(verificationType, s)) {
|
||||
cmdbuf.append('"').append(s);
|
||||
|
||||
// The code protects the [java.exe] and console command line
|
||||
// parser, that interprets the [\"] combination as an escape
|
||||
// sequence for the ["] char.
|
||||
// http://msdn.microsoft.com/en-us/library/17w5ykft.aspx
|
||||
//
|
||||
// If the argument is an FS path, doubling of the tail [\]
|
||||
// char is not a problem for non-console applications.
|
||||
//
|
||||
// The [\"] sequence is not an escape sequence for the [cmd.exe]
|
||||
// command line parser. The case of the [""] tail escape
|
||||
// sequence could not be realized due to the argument validation
|
||||
// procedure.
|
||||
if ((verificationType != VERIFICATION_CMD_BAT) && s.endsWith("\\")) {
|
||||
cmdbuf.append('\\');
|
||||
}
|
||||
cmdbuf.append('"');
|
||||
} else {
|
||||
cmdbuf.append(s);
|
||||
}
|
||||
}
|
||||
return cmdbuf.toString();
|
||||
}
|
||||
|
||||
private static boolean isQuoted(boolean noQuotesInside, String arg,
|
||||
String errorMessage) {
|
||||
int lastPos = arg.length() - 1;
|
||||
if (lastPos >=1 && arg.charAt(0) == '"' && arg.charAt(lastPos) == '"') {
|
||||
// The argument has already been quoted.
|
||||
if (noQuotesInside) {
|
||||
if (arg.indexOf('"', 1) != lastPos) {
|
||||
// There is ["] inside.
|
||||
throw new IllegalArgumentException(errorMessage);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (noQuotesInside) {
|
||||
if (arg.indexOf('"') >= 0) {
|
||||
// There is ["] inside.
|
||||
throw new IllegalArgumentException(errorMessage);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean needsEscaping(int verificationType, String arg) {
|
||||
// Switch off MS heuristic for internal ["].
|
||||
// Please, use the explicit [cmd.exe] call
|
||||
// if you need the internal ["].
|
||||
// Example: "cmd.exe", "/C", "Extended_MS_Syntax"
|
||||
|
||||
// For [.exe] or [.com] file the unpaired/internal ["]
|
||||
// in the argument is not a problem.
|
||||
boolean argIsQuoted = isQuoted(
|
||||
(verificationType == VERIFICATION_CMD_BAT),
|
||||
arg, "Argument has embedded quote, use the explicit CMD.EXE call.");
|
||||
|
||||
if (!argIsQuoted) {
|
||||
char testEscape[] = ESCAPE_VERIFICATION[verificationType];
|
||||
for (int i = 0; i < testEscape.length; ++i) {
|
||||
if (arg.indexOf(testEscape[i]) >= 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String getExecutablePath(String path)
|
||||
throws IOException
|
||||
{
|
||||
boolean pathIsQuoted = isQuoted(true, path,
|
||||
"Executable name has embedded quote, split the arguments");
|
||||
|
||||
// Win32 CreateProcess requires path to be normalized
|
||||
File fileToRun = new File(pathIsQuoted
|
||||
? path.substring(1, path.length() - 1)
|
||||
: path);
|
||||
|
||||
// From the [CreateProcess] function documentation:
|
||||
//
|
||||
// "If the file name does not contain an extension, .exe is appended.
|
||||
// Therefore, if the file name extension is .com, this parameter
|
||||
// must include the .com extension. If the file name ends in
|
||||
// a period (.) with no extension, or if the file name contains a path,
|
||||
// .exe is not appended."
|
||||
//
|
||||
// "If the file name !does not contain a directory path!,
|
||||
// the system searches for the executable file in the following
|
||||
// sequence:..."
|
||||
//
|
||||
// In practice ANY non-existent path is extended by [.exe] extension
|
||||
// in the [CreateProcess] funcion with the only exception:
|
||||
// the path ends by (.)
|
||||
|
||||
return fileToRun.getPath();
|
||||
}
|
||||
|
||||
|
||||
private boolean isShellFile(String executablePath) {
|
||||
String upPath = executablePath.toUpperCase();
|
||||
return (upPath.endsWith(".CMD") || upPath.endsWith(".BAT"));
|
||||
}
|
||||
|
||||
private String quoteString(String arg) {
|
||||
StringBuilder argbuf = new StringBuilder(arg.length() + 2);
|
||||
return argbuf.append('"').append(arg).append('"').toString();
|
||||
}
|
||||
|
||||
|
||||
private cli.System.Diagnostics.Process handle;
|
||||
private OutputStream stdin_stream;
|
||||
private InputStream stdout_stream;
|
||||
private InputStream stderr_stream;
|
||||
|
||||
private ProcessImpl(final String cmd[],
|
||||
private ProcessImpl(String cmd[],
|
||||
final java.util.Map<String,String> envblock,
|
||||
final String path,
|
||||
final Stream[] stdHandles,
|
||||
final boolean redirectErrorStream)
|
||||
throws IOException
|
||||
{
|
||||
// Win32 CreateProcess requires cmd[0] to be normalized
|
||||
cmd[0] = new File(cmd[0]).getPath();
|
||||
|
||||
// give the runtime an opportunity to map executables from VFS to a real executable
|
||||
cmd[0] = mapVfsExecutable(cmd[0]);
|
||||
|
||||
StringBuilder cmdbuf = new StringBuilder(80);
|
||||
for (int i = 0; i < cmd.length; i++) {
|
||||
if (i > 0) {
|
||||
cmdbuf.append(' ');
|
||||
}
|
||||
String s = cmd[i];
|
||||
if (s.indexOf(' ') >= 0 || s.indexOf('\t') >= 0) {
|
||||
if (s.charAt(0) != '"') {
|
||||
cmdbuf.append('"');
|
||||
cmdbuf.append(s);
|
||||
if (s.endsWith("\\")) {
|
||||
cmdbuf.append("\\");
|
||||
}
|
||||
cmdbuf.append('"');
|
||||
} else if (s.endsWith("\"")) {
|
||||
/* The argument has already been quoted. */
|
||||
cmdbuf.append(s);
|
||||
} else {
|
||||
/* Unmatched quote for the argument. */
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
} else {
|
||||
cmdbuf.append(s);
|
||||
}
|
||||
String cmdstr;
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
boolean allowAmbiguousCommands = false;
|
||||
if (security == null) {
|
||||
allowAmbiguousCommands = true;
|
||||
String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");
|
||||
if (value != null)
|
||||
allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
|
||||
}
|
||||
if (allowAmbiguousCommands) {
|
||||
// Legacy mode.
|
||||
|
||||
// Normalize path if possible.
|
||||
String executablePath = new File(cmd[0]).getPath();
|
||||
|
||||
// No worry about internal, unpaired ["], and redirection/piping.
|
||||
if (needsEscaping(VERIFICATION_LEGACY, executablePath) )
|
||||
executablePath = quoteString(executablePath);
|
||||
|
||||
cmdstr = createCommandLine(
|
||||
//legacy mode doesn't worry about extended verification
|
||||
VERIFICATION_LEGACY,
|
||||
executablePath,
|
||||
cmd);
|
||||
} else {
|
||||
String executablePath;
|
||||
try {
|
||||
executablePath = getExecutablePath(cmd[0]);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Workaround for the calls like
|
||||
// Runtime.getRuntime().exec("\"C:\\Program Files\\foo\" bar")
|
||||
|
||||
// No chance to avoid CMD/BAT injection, except to do the work
|
||||
// right from the beginning. Otherwise we have too many corner
|
||||
// cases from
|
||||
// Runtime.getRuntime().exec(String[] cmd [, ...])
|
||||
// calls with internal ["] and escape sequences.
|
||||
|
||||
// Restore original command line.
|
||||
StringBuilder join = new StringBuilder();
|
||||
// terminal space in command line is ok
|
||||
for (String s : cmd)
|
||||
join.append(s).append(' ');
|
||||
|
||||
// Parse the command line again.
|
||||
cmd = getTokensFromCommand(join.toString());
|
||||
executablePath = getExecutablePath(cmd[0]);
|
||||
|
||||
// Check new executable name once more
|
||||
if (security != null)
|
||||
security.checkExec(executablePath);
|
||||
}
|
||||
|
||||
// Quotation protects from interpretation of the [path] argument as
|
||||
// start of longer path with spaces. Quotation has no influence to
|
||||
// [.exe] extension heuristic.
|
||||
cmdstr = createCommandLine(
|
||||
// We need the extended verification procedure for CMD files.
|
||||
isShellFile(executablePath)
|
||||
? VERIFICATION_CMD_BAT
|
||||
: VERIFICATION_WIN32,
|
||||
quoteString(executablePath),
|
||||
cmd);
|
||||
}
|
||||
String cmdstr = cmdbuf.toString();
|
||||
|
||||
handle = create(cmdstr, envblock, path,
|
||||
stdHandles, redirectErrorStream);
|
||||
@ -261,6 +466,7 @@ final class ProcessImpl extends Process {
|
||||
throw new InterruptedException();
|
||||
return exitValue();
|
||||
}
|
||||
|
||||
private static void waitForInterruptibly(cli.System.Diagnostics.Process handle) throws InterruptedException {
|
||||
// to be interruptable we have to use polling
|
||||
// (on .NET 2.0 WaitForExit is actually interruptible, but this isn't documented)
|
||||
@ -269,7 +475,53 @@ final class ProcessImpl extends Process {
|
||||
;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean waitFor(long timeout, TimeUnit unit)
|
||||
throws InterruptedException
|
||||
{
|
||||
if (handle.get_HasExited()) return true;
|
||||
if (timeout <= 0) return false;
|
||||
|
||||
long msTimeout = unit.toMillis(timeout);
|
||||
|
||||
waitForTimeoutInterruptibly(handle, msTimeout);
|
||||
if (Thread.interrupted())
|
||||
throw new InterruptedException();
|
||||
return handle.get_HasExited();
|
||||
}
|
||||
|
||||
private static void waitForTimeoutInterruptibly(
|
||||
cli.System.Diagnostics.Process handle, long timeout) {
|
||||
long now = System.currentTimeMillis();
|
||||
long exp = now + timeout;
|
||||
if (exp < now) {
|
||||
// if we overflowed, just wait for a really long time
|
||||
exp = Long.MAX_VALUE;
|
||||
}
|
||||
Thread current = Thread.currentThread();
|
||||
for (;;) {
|
||||
if (current.isInterrupted()) {
|
||||
return;
|
||||
}
|
||||
// wait for a maximum of 100 ms to be interruptible
|
||||
if (handle.WaitForExit((int)Math.min(100, exp - now))) {
|
||||
return;
|
||||
}
|
||||
now = System.currentTimeMillis();
|
||||
if (now >= exp) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() { terminateProcess(handle); }
|
||||
|
||||
@Override
|
||||
public Process destroyForcibly() {
|
||||
destroy();
|
||||
return this;
|
||||
}
|
||||
|
||||
private static void terminateProcess(cli.System.Diagnostics.Process handle) {
|
||||
try {
|
||||
if (false) throw new cli.System.ComponentModel.Win32Exception();
|
||||
@ -280,10 +532,21 @@ final class ProcessImpl extends Process {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAlive() {
|
||||
return isProcessAlive(handle);
|
||||
}
|
||||
|
||||
private static boolean isProcessAlive(cli.System.Diagnostics.Process handle) {
|
||||
return !handle.get_HasExited();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a process using the win32 function CreateProcess.
|
||||
* The method is synchronized due to MS kb315939 problem.
|
||||
* All native handles should restore the inherit flag at the end of call.
|
||||
*
|
||||
* @param cmdstr the Windows commandline
|
||||
* @param cmdstr the Windows command line
|
||||
* @param envblock NUL-separated, double-NUL-terminated list of
|
||||
* environment strings in VAR=VALUE form
|
||||
* @param dir the working directory of the process, or null if
|
||||
@ -312,7 +575,8 @@ final class ProcessImpl extends Process {
|
||||
argumentsStart++;
|
||||
}
|
||||
|
||||
ProcessStartInfo si = new ProcessStartInfo(cmdstr.substring(0, programEnd), cmdstr.substring(argumentsStart));
|
||||
String fileName = cmdstr.substring(0, programEnd);
|
||||
ProcessStartInfo si = new ProcessStartInfo(mapVfsExecutable(fileName), cmdstr.substring(argumentsStart));
|
||||
si.set_UseShellExecute(false);
|
||||
si.set_RedirectStandardError(true);
|
||||
si.set_RedirectStandardOutput(true);
|
||||
@ -338,6 +602,27 @@ final class ProcessImpl extends Process {
|
||||
} catch (cli.System.InvalidOperationException x2) {
|
||||
throw new IOException(x2.getMessage());
|
||||
}
|
||||
|
||||
// if any of the handles is redirected to/from a file,
|
||||
// we need to close the files as soon as the process exits
|
||||
if (stdHandles[0] instanceof FileStream
|
||||
|| stdHandles[1] instanceof FileStream
|
||||
|| stdHandles[2] instanceof FileStream) {
|
||||
final Stream s0 = stdHandles[0];
|
||||
final Stream s1 = stdHandles[1];
|
||||
final Stream s2 = stdHandles[2];
|
||||
proc.set_EnableRaisingEvents(true);
|
||||
proc.add_Exited(new EventHandler(new EventHandler.Method() {
|
||||
public void Invoke(Object sender, EventArgs e) {
|
||||
if (s0 instanceof FileStream)
|
||||
s0.Close();
|
||||
if (s1 instanceof FileStream)
|
||||
s1.Close();
|
||||
if (s2 instanceof FileStream)
|
||||
s2.Close();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
Stream stdin = proc.get_StandardInput().get_BaseStream();
|
||||
Stream stdout = proc.get_StandardOutput().get_BaseStream();
|
||||
|
2578
external/ikvm/openjdk/java/lang/Thread.java
vendored
2578
external/ikvm/openjdk/java/lang/Thread.java
vendored
File diff suppressed because it is too large
Load Diff
1
external/ikvm/openjdk/java/lang/Thread.java.REMOVED.git-id
vendored
Normal file
1
external/ikvm/openjdk/java/lang/Thread.java.REMOVED.git-id
vendored
Normal file
@ -0,0 +1 @@
|
||||
7ab53c76bb97c702c39866643a2547962ef3ead6
|
Reference in New Issue
Block a user