mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 22:34:27 +02:00
8343958: Remove security manager impl in java.lang.Process and java.lang.Runtime.exec
Reviewed-by: jpai, mullan, alanb
This commit is contained in:
parent
5ac330b1ac
commit
168b18ec68
4 changed files with 55 additions and 169 deletions
|
@ -339,11 +339,6 @@ public final class ProcessBuilder
|
||||||
* @see System#getenv()
|
* @see System#getenv()
|
||||||
*/
|
*/
|
||||||
public Map<String,String> environment() {
|
public Map<String,String> environment() {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager security = System.getSecurityManager();
|
|
||||||
if (security != null)
|
|
||||||
security.checkPermission(new RuntimePermission("getenv.*"));
|
|
||||||
|
|
||||||
if (environment == null)
|
if (environment == null)
|
||||||
environment = ProcessEnvironment.environment();
|
environment = ProcessEnvironment.environment();
|
||||||
|
|
||||||
|
@ -1069,11 +1064,6 @@ public final class ProcessBuilder
|
||||||
// Throws IndexOutOfBoundsException if command is empty
|
// Throws IndexOutOfBoundsException if command is empty
|
||||||
String prog = cmdarray[0];
|
String prog = cmdarray[0];
|
||||||
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager security = System.getSecurityManager();
|
|
||||||
if (security != null)
|
|
||||||
security.checkExec(prog);
|
|
||||||
|
|
||||||
String dir = directory == null ? null : directory.toString();
|
String dir = directory == null ? null : directory.toString();
|
||||||
|
|
||||||
for (String s : cmdarray) {
|
for (String s : cmdarray) {
|
||||||
|
@ -1112,24 +1102,13 @@ public final class ProcessBuilder
|
||||||
}
|
}
|
||||||
return process;
|
return process;
|
||||||
} catch (IOException | IllegalArgumentException e) {
|
} catch (IOException | IllegalArgumentException e) {
|
||||||
String exceptionInfo = ": " + e.getMessage();
|
|
||||||
Throwable cause = e;
|
|
||||||
if ((e instanceof IOException) && security != null) {
|
|
||||||
// Can not disclose the fail reason for read-protected files.
|
|
||||||
try {
|
|
||||||
security.checkRead(prog);
|
|
||||||
} catch (SecurityException se) {
|
|
||||||
exceptionInfo = "";
|
|
||||||
cause = se;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// It's much easier for us to create a high-quality error
|
// It's much easier for us to create a high-quality error
|
||||||
// message than the low-level C code which found the problem.
|
// message than the low-level C code which found the problem.
|
||||||
throw new IOException(
|
throw new IOException(
|
||||||
"Cannot run program \"" + prog + "\""
|
"Cannot run program \"" + prog + "\""
|
||||||
+ (dir == null ? "" : " (in directory \"" + dir + "\")")
|
+ (dir == null ? "" : " (in directory \"" + dir + "\")")
|
||||||
+ exceptionInfo,
|
+ ": " + e.getMessage(),
|
||||||
cause);
|
e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -84,28 +84,28 @@ final class ProcessHandleImpl implements ProcessHandle {
|
||||||
/**
|
/**
|
||||||
* The thread pool of "process reaper" daemon threads.
|
* The thread pool of "process reaper" daemon threads.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
private static final Executor processReaperExecutor = initReaper();
|
||||||
private static final Executor processReaperExecutor =
|
|
||||||
AccessController.doPrivileged((PrivilegedAction<Executor>) () -> {
|
|
||||||
// Initialize ThreadLocalRandom now to avoid using the smaller stack
|
|
||||||
// of the processReaper threads.
|
|
||||||
ThreadLocalRandom.current();
|
|
||||||
|
|
||||||
// For a debug build, the stack shadow zone is larger;
|
private static Executor initReaper() {
|
||||||
// Increase the total stack size to avoid potential stack overflow.
|
// Initialize ThreadLocalRandom now to avoid using the smaller stack
|
||||||
int debugDelta = "release".equals(System.getProperty("jdk.debug")) ? 0 : (4*4096);
|
// of the processReaper threads.
|
||||||
final long stackSize = Boolean.getBoolean("jdk.lang.processReaperUseDefaultStackSize")
|
ThreadLocalRandom.current();
|
||||||
? 0 : REAPER_DEFAULT_STACKSIZE + debugDelta;
|
|
||||||
|
|
||||||
ThreadFactory threadFactory = grimReaper -> {
|
// For a debug build, the stack shadow zone is larger;
|
||||||
Thread t = InnocuousThread.newSystemThread("process reaper", grimReaper,
|
// Increase the total stack size to avoid potential stack overflow.
|
||||||
stackSize, Thread.MAX_PRIORITY);
|
int debugDelta = "release".equals(System.getProperty("jdk.debug")) ? 0 : (4 * 4096);
|
||||||
privilegedThreadSetDaemon(t, true);
|
final long stackSize = Boolean.getBoolean("jdk.lang.processReaperUseDefaultStackSize")
|
||||||
return t;
|
? 0 : REAPER_DEFAULT_STACKSIZE + debugDelta;
|
||||||
};
|
|
||||||
|
|
||||||
return Executors.newCachedThreadPool(threadFactory);
|
ThreadFactory threadFactory = grimReaper -> {
|
||||||
});
|
Thread t = InnocuousThread.newSystemThread("process reaper", grimReaper,
|
||||||
|
stackSize, Thread.MAX_PRIORITY);
|
||||||
|
t.setDaemon(true);
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
|
||||||
|
return Executors.newCachedThreadPool(threadFactory);
|
||||||
|
}
|
||||||
|
|
||||||
private static class ExitCompletion extends CompletableFuture<Integer> {
|
private static class ExitCompletion extends CompletableFuture<Integer> {
|
||||||
final boolean isReaping;
|
final boolean isReaping;
|
||||||
|
@ -115,22 +115,6 @@ final class ProcessHandleImpl implements ProcessHandle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
private static void privilegedThreadSetName(Thread thread, String name) {
|
|
||||||
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
|
|
||||||
thread.setName(name);
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
private static void privilegedThreadSetDaemon(Thread thread, boolean on) {
|
|
||||||
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
|
|
||||||
thread.setDaemon(on);
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a CompletableFuture that completes with process exit status when
|
* Returns a CompletableFuture that completes with process exit status when
|
||||||
* the process completes.
|
* the process completes.
|
||||||
|
@ -158,7 +142,7 @@ final class ProcessHandleImpl implements ProcessHandle {
|
||||||
public void run() {
|
public void run() {
|
||||||
Thread t = Thread.currentThread();
|
Thread t = Thread.currentThread();
|
||||||
String threadName = t.getName();
|
String threadName = t.getName();
|
||||||
privilegedThreadSetName(t, "process reaper (pid " + pid + ")");
|
t.setName("process reaper (pid " + pid + ")");
|
||||||
try {
|
try {
|
||||||
int exitValue = waitForProcessExit0(pid, shouldReap);
|
int exitValue = waitForProcessExit0(pid, shouldReap);
|
||||||
if (exitValue == NOT_A_CHILD) {
|
if (exitValue == NOT_A_CHILD) {
|
||||||
|
@ -189,7 +173,7 @@ final class ProcessHandleImpl implements ProcessHandle {
|
||||||
completions.remove(pid, newCompletion);
|
completions.remove(pid, newCompletion);
|
||||||
} finally {
|
} finally {
|
||||||
// Restore thread name
|
// Restore thread name
|
||||||
privilegedThreadSetName(t, threadName);
|
t.setName(threadName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -255,14 +239,8 @@ final class ProcessHandleImpl implements ProcessHandle {
|
||||||
* @param pid the native process identifier
|
* @param pid the native process identifier
|
||||||
* @return The ProcessHandle for the pid if the process is alive;
|
* @return The ProcessHandle for the pid if the process is alive;
|
||||||
* or {@code null} if the process ID does not exist in the native system.
|
* or {@code null} if the process ID does not exist in the native system.
|
||||||
* @throws SecurityException if RuntimePermission("manageProcess") is not granted
|
|
||||||
*/
|
*/
|
||||||
static Optional<ProcessHandle> get(long pid) {
|
static Optional<ProcessHandle> get(long pid) {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
sm.checkPermission(new RuntimePermission("manageProcess"));
|
|
||||||
}
|
|
||||||
long start = isAlive0(pid);
|
long start = isAlive0(pid);
|
||||||
return (start >= 0)
|
return (start >= 0)
|
||||||
? Optional.of(new ProcessHandleImpl(pid, start))
|
? Optional.of(new ProcessHandleImpl(pid, start))
|
||||||
|
@ -296,14 +274,8 @@ final class ProcessHandleImpl implements ProcessHandle {
|
||||||
* Returns the ProcessHandle for the current native process.
|
* Returns the ProcessHandle for the current native process.
|
||||||
*
|
*
|
||||||
* @return The ProcessHandle for the OS process.
|
* @return The ProcessHandle for the OS process.
|
||||||
* @throws SecurityException if RuntimePermission("manageProcess") is not granted
|
|
||||||
*/
|
*/
|
||||||
public static ProcessHandleImpl current() {
|
public static ProcessHandleImpl current() {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
sm.checkPermission(new RuntimePermission("manageProcess"));
|
|
||||||
}
|
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,15 +291,8 @@ final class ProcessHandleImpl implements ProcessHandle {
|
||||||
*
|
*
|
||||||
* @return a ProcessHandle of the parent process; {@code null} is returned
|
* @return a ProcessHandle of the parent process; {@code null} is returned
|
||||||
* if the child process does not have a parent
|
* if the child process does not have a parent
|
||||||
* @throws SecurityException if permission is not granted by the
|
|
||||||
* security policy
|
|
||||||
*/
|
*/
|
||||||
public Optional<ProcessHandle> parent() {
|
public Optional<ProcessHandle> parent() {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
sm.checkPermission(new RuntimePermission("manageProcess"));
|
|
||||||
}
|
|
||||||
long ppid = parent0(pid, startTime);
|
long ppid = parent0(pid, startTime);
|
||||||
if (ppid <= 0) {
|
if (ppid <= 0) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
|
@ -442,11 +407,6 @@ final class ProcessHandleImpl implements ProcessHandle {
|
||||||
* @return a stream of ProcessHandles
|
* @return a stream of ProcessHandles
|
||||||
*/
|
*/
|
||||||
static Stream<ProcessHandle> children(long pid) {
|
static Stream<ProcessHandle> children(long pid) {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
sm.checkPermission(new RuntimePermission("manageProcess"));
|
|
||||||
}
|
|
||||||
int size = 100;
|
int size = 100;
|
||||||
long[] childpids = null;
|
long[] childpids = null;
|
||||||
long[] starttimes = null;
|
long[] starttimes = null;
|
||||||
|
@ -463,11 +423,6 @@ final class ProcessHandleImpl implements ProcessHandle {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<ProcessHandle> descendants() {
|
public Stream<ProcessHandle> descendants() {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
sm.checkPermission(new RuntimePermission("manageProcess"));
|
|
||||||
}
|
|
||||||
int size = 100;
|
int size = 100;
|
||||||
long[] pids = null;
|
long[] pids = null;
|
||||||
long[] ppids = null;
|
long[] ppids = null;
|
||||||
|
|
|
@ -42,14 +42,10 @@ import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.locks.Condition;
|
import java.util.concurrent.locks.Condition;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedActionException;
|
|
||||||
import java.security.PrivilegedExceptionAction;
|
|
||||||
import jdk.internal.access.JavaIOFileDescriptorAccess;
|
import jdk.internal.access.JavaIOFileDescriptorAccess;
|
||||||
import jdk.internal.access.SharedSecrets;
|
import jdk.internal.access.SharedSecrets;
|
||||||
import jdk.internal.util.OperatingSystem;
|
import jdk.internal.util.OperatingSystem;
|
||||||
import jdk.internal.util.StaticProperty;
|
import jdk.internal.util.StaticProperty;
|
||||||
import sun.security.action.GetPropertyAction;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* java.lang.Process subclass in the UNIX environment.
|
* java.lang.Process subclass in the UNIX environment.
|
||||||
|
@ -95,7 +91,7 @@ final class ProcessImpl extends Process {
|
||||||
* @throws Error if the requested launch mechanism is not found or valid
|
* @throws Error if the requested launch mechanism is not found or valid
|
||||||
*/
|
*/
|
||||||
private static LaunchMechanism launchMechanism() {
|
private static LaunchMechanism launchMechanism() {
|
||||||
String s = GetPropertyAction.privilegedGetProperty("jdk.lang.Process.launchMechanism");
|
String s = System.getProperty("jdk.lang.Process.launchMechanism");
|
||||||
if (s == null) {
|
if (s == null) {
|
||||||
return LaunchMechanism.POSIX_SPAWN;
|
return LaunchMechanism.POSIX_SPAWN;
|
||||||
}
|
}
|
||||||
|
@ -282,7 +278,6 @@ final class ProcessImpl extends Process {
|
||||||
boolean redirectErrorStream)
|
boolean redirectErrorStream)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
private ProcessImpl(final byte[] prog,
|
private ProcessImpl(final byte[] prog,
|
||||||
final byte[] argBlock, final int argc,
|
final byte[] argBlock, final int argc,
|
||||||
final byte[] envBlock, final int envc,
|
final byte[] envBlock, final int envc,
|
||||||
|
@ -302,14 +297,7 @@ final class ProcessImpl extends Process {
|
||||||
redirectErrorStream);
|
redirectErrorStream);
|
||||||
processHandle = ProcessHandleImpl.getInternal(pid);
|
processHandle = ProcessHandleImpl.getInternal(pid);
|
||||||
|
|
||||||
try {
|
initStreams(fds, forceNullOutputStream);
|
||||||
AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
|
|
||||||
initStreams(fds, forceNullOutputStream);
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
} catch (PrivilegedActionException ex) {
|
|
||||||
throw (IOException) ex.getCause();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static FileDescriptor newFileDescriptor(int fd) {
|
static FileDescriptor newFileDescriptor(int fd) {
|
||||||
|
@ -507,11 +495,6 @@ final class ProcessImpl extends Process {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProcessHandle toHandle() {
|
public ProcessHandle toHandle() {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
sm.checkPermission(new RuntimePermission("manageProcess"));
|
|
||||||
}
|
|
||||||
return processHandle;
|
return processHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,6 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.lang.ProcessBuilder.Redirect;
|
import java.lang.ProcessBuilder.Redirect;
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
@ -48,7 +46,6 @@ import jdk.internal.access.JavaIOFileDescriptorAccess;
|
||||||
import jdk.internal.access.SharedSecrets;
|
import jdk.internal.access.SharedSecrets;
|
||||||
import jdk.internal.ref.CleanerFactory;
|
import jdk.internal.ref.CleanerFactory;
|
||||||
import jdk.internal.misc.Blocker;
|
import jdk.internal.misc.Blocker;
|
||||||
import sun.security.action.GetPropertyAction;
|
|
||||||
|
|
||||||
/* This class is for the exclusive use of ProcessBuilder.start() to
|
/* This class is for the exclusive use of ProcessBuilder.start() to
|
||||||
* create new processes.
|
* create new processes.
|
||||||
|
@ -71,25 +68,15 @@ final class ProcessImpl extends Process {
|
||||||
* to append to a file does not open the file in a manner that guarantees
|
* to append to a file does not open the file in a manner that guarantees
|
||||||
* that writes by the child process will be atomic.
|
* that writes by the child process will be atomic.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
|
||||||
private static FileOutputStream newFileOutputStream(File f, boolean append)
|
private static FileOutputStream newFileOutputStream(File f, boolean append)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
if (append) {
|
if (append) {
|
||||||
String path = f.getPath();
|
String path = f.getPath();
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null)
|
|
||||||
sm.checkWrite(path);
|
|
||||||
long handle = openForAtomicAppend(path);
|
long handle = openForAtomicAppend(path);
|
||||||
final FileDescriptor fd = new FileDescriptor();
|
final FileDescriptor fd = new FileDescriptor();
|
||||||
fdAccess.setHandle(fd, handle);
|
fdAccess.setHandle(fd, handle);
|
||||||
return AccessController.doPrivileged(
|
return new FileOutputStream(fd);
|
||||||
new PrivilegedAction<FileOutputStream>() {
|
|
||||||
public FileOutputStream run() {
|
|
||||||
return new FileOutputStream(fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
return new FileOutputStream(f);
|
return new FileOutputStream(f);
|
||||||
}
|
}
|
||||||
|
@ -424,7 +411,6 @@ final class ProcessImpl extends Process {
|
||||||
private InputStream stdout_stream;
|
private InputStream stdout_stream;
|
||||||
private InputStream stderr_stream;
|
private InputStream stderr_stream;
|
||||||
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
private ProcessImpl(String cmd[],
|
private ProcessImpl(String cmd[],
|
||||||
final String envblock,
|
final String envblock,
|
||||||
final String path,
|
final String path,
|
||||||
|
@ -434,13 +420,10 @@ final class ProcessImpl extends Process {
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
String cmdstr;
|
String cmdstr;
|
||||||
final SecurityManager security = System.getSecurityManager();
|
final String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands", "true");
|
||||||
final String value = GetPropertyAction.
|
|
||||||
privilegedGetProperty("jdk.lang.Process.allowAmbiguousCommands",
|
|
||||||
(security == null ? "true" : "false"));
|
|
||||||
final boolean allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
|
final boolean allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
|
||||||
|
|
||||||
if (allowAmbiguousCommands && security == null) {
|
if (allowAmbiguousCommands) {
|
||||||
// Legacy mode.
|
// Legacy mode.
|
||||||
|
|
||||||
// Normalize path if possible.
|
// Normalize path if possible.
|
||||||
|
@ -478,10 +461,6 @@ final class ProcessImpl extends Process {
|
||||||
// Parse the command line again.
|
// Parse the command line again.
|
||||||
cmd = getTokensFromCommand(join.toString());
|
cmd = getTokensFromCommand(join.toString());
|
||||||
executablePath = getExecutablePath(cmd[0]);
|
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
|
// Quotation protects from interpretation of the [path] argument as
|
||||||
|
@ -505,39 +484,34 @@ final class ProcessImpl extends Process {
|
||||||
|
|
||||||
processHandle = ProcessHandleImpl.getInternal(getProcessId0(handle));
|
processHandle = ProcessHandleImpl.getInternal(getProcessId0(handle));
|
||||||
|
|
||||||
java.security.AccessController.doPrivileged(
|
if (stdHandles[0] == -1L)
|
||||||
new java.security.PrivilegedAction<Void>() {
|
stdin_stream = ProcessBuilder.NullOutputStream.INSTANCE;
|
||||||
public Void run() {
|
else {
|
||||||
if (stdHandles[0] == -1L)
|
FileDescriptor stdin_fd = new FileDescriptor();
|
||||||
stdin_stream = ProcessBuilder.NullOutputStream.INSTANCE;
|
fdAccess.setHandle(stdin_fd, stdHandles[0]);
|
||||||
else {
|
fdAccess.registerCleanup(stdin_fd);
|
||||||
FileDescriptor stdin_fd = new FileDescriptor();
|
stdin_stream = new BufferedOutputStream(
|
||||||
fdAccess.setHandle(stdin_fd, stdHandles[0]);
|
new PipeOutputStream(stdin_fd));
|
||||||
fdAccess.registerCleanup(stdin_fd);
|
}
|
||||||
stdin_stream = new BufferedOutputStream(
|
|
||||||
new PipeOutputStream(stdin_fd));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stdHandles[1] == -1L || forceNullOutputStream)
|
if (stdHandles[1] == -1L || forceNullOutputStream)
|
||||||
stdout_stream = ProcessBuilder.NullInputStream.INSTANCE;
|
stdout_stream = ProcessBuilder.NullInputStream.INSTANCE;
|
||||||
else {
|
else {
|
||||||
FileDescriptor stdout_fd = new FileDescriptor();
|
FileDescriptor stdout_fd = new FileDescriptor();
|
||||||
fdAccess.setHandle(stdout_fd, stdHandles[1]);
|
fdAccess.setHandle(stdout_fd, stdHandles[1]);
|
||||||
fdAccess.registerCleanup(stdout_fd);
|
fdAccess.registerCleanup(stdout_fd);
|
||||||
stdout_stream = new BufferedInputStream(
|
stdout_stream = new BufferedInputStream(
|
||||||
new PipeInputStream(stdout_fd));
|
new PipeInputStream(stdout_fd));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stdHandles[2] == -1L)
|
if (stdHandles[2] == -1L)
|
||||||
stderr_stream = ProcessBuilder.NullInputStream.INSTANCE;
|
stderr_stream = ProcessBuilder.NullInputStream.INSTANCE;
|
||||||
else {
|
else {
|
||||||
FileDescriptor stderr_fd = new FileDescriptor();
|
FileDescriptor stderr_fd = new FileDescriptor();
|
||||||
fdAccess.setHandle(stderr_fd, stdHandles[2]);
|
fdAccess.setHandle(stderr_fd, stdHandles[2]);
|
||||||
fdAccess.registerCleanup(stderr_fd);
|
fdAccess.registerCleanup(stderr_fd);
|
||||||
stderr_stream = new PipeInputStream(stderr_fd);
|
stderr_stream = new PipeInputStream(stderr_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null; }});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public OutputStream getOutputStream() {
|
public OutputStream getOutputStream() {
|
||||||
|
@ -632,11 +606,6 @@ final class ProcessImpl extends Process {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProcessHandle toHandle() {
|
public ProcessHandle toHandle() {
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
sm.checkPermission(new RuntimePermission("manageProcess"));
|
|
||||||
}
|
|
||||||
return processHandle;
|
return processHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue