mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-24 04:54:40 +02:00
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
Reviewed-by: alanb
This commit is contained in:
parent
d558c37a5b
commit
54ddaf5ab7
9 changed files with 598 additions and 26 deletions
|
@ -26,7 +26,7 @@
|
|||
* @bug 4199068 4738465 4937983 4930681 4926230 4931433 4932663 4986689
|
||||
* 5026830 5023243 5070673 4052517 4811767 6192449 6397034 6413313
|
||||
* 6464154 6523983 6206031 4960438 6631352 6631966 6850957 6850958
|
||||
* 4947220 7018606 7034570
|
||||
* 4947220 7018606 7034570 4244896
|
||||
* @summary Basic tests for Process and Environment Variable code
|
||||
* @run main/othervm/timeout=300 Basic
|
||||
* @author Martin Buchholz
|
||||
|
@ -38,6 +38,7 @@ import static java.lang.ProcessBuilder.Redirect.*;
|
|||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.security.*;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.Matcher;
|
||||
|
@ -636,6 +637,44 @@ public class Basic {
|
|||
static boolean is() { return is; }
|
||||
}
|
||||
|
||||
static class DelegatingProcess extends Process {
|
||||
final Process p;
|
||||
|
||||
DelegatingProcess(Process p) {
|
||||
this.p = p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
p.destroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int exitValue() {
|
||||
return p.exitValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int waitFor() throws InterruptedException {
|
||||
return p.waitFor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream getOutputStream() {
|
||||
return p.getOutputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() {
|
||||
return p.getInputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getErrorStream() {
|
||||
return p.getErrorStream();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean matches(String str, String regex) {
|
||||
return Pattern.compile(regex).matcher(str).find();
|
||||
}
|
||||
|
@ -2090,6 +2129,112 @@ public class Basic {
|
|||
policy.setPermissions(new RuntimePermission("setSecurityManager"));
|
||||
System.setSecurityManager(null);
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Check that Process.isAlive() &
|
||||
// Process.waitFor(0, TimeUnit.MILLISECONDS) work as expected.
|
||||
//----------------------------------------------------------------
|
||||
try {
|
||||
List<String> childArgs = new ArrayList<String>(javaChildArgs);
|
||||
childArgs.add("sleep");
|
||||
final Process p = new ProcessBuilder(childArgs).start();
|
||||
long start = System.nanoTime();
|
||||
if (!p.isAlive() || p.waitFor(0, TimeUnit.MILLISECONDS)) {
|
||||
fail("Test failed: Process exited prematurely");
|
||||
}
|
||||
long end = System.nanoTime();
|
||||
// give waitFor(timeout) a wide berth (100ms)
|
||||
if ((end - start) > 100000000)
|
||||
fail("Test failed: waitFor took too long");
|
||||
|
||||
p.destroy();
|
||||
p.waitFor();
|
||||
|
||||
if (p.isAlive() ||
|
||||
!p.waitFor(0, TimeUnit.MILLISECONDS))
|
||||
{
|
||||
fail("Test failed: Process still alive - please terminate " +
|
||||
p.toString() + " manually");
|
||||
}
|
||||
} catch (Throwable t) { unexpected(t); }
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Check that Process.waitFor(timeout, TimeUnit.MILLISECONDS)
|
||||
// works as expected.
|
||||
//----------------------------------------------------------------
|
||||
try {
|
||||
List<String> childArgs = new ArrayList<String>(javaChildArgs);
|
||||
childArgs.add("sleep");
|
||||
final Process p = new ProcessBuilder(childArgs).start();
|
||||
long start = System.nanoTime();
|
||||
|
||||
p.waitFor(1000, TimeUnit.MILLISECONDS);
|
||||
|
||||
long end = System.nanoTime();
|
||||
if ((end - start) < 500000000)
|
||||
fail("Test failed: waitFor didn't take long enough");
|
||||
|
||||
p.destroy();
|
||||
|
||||
start = System.nanoTime();
|
||||
p.waitFor(1000, TimeUnit.MILLISECONDS);
|
||||
end = System.nanoTime();
|
||||
if ((end - start) > 100000000)
|
||||
fail("Test failed: waitFor took too long on a dead process.");
|
||||
} catch (Throwable t) { unexpected(t); }
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Check that Process.waitFor(timeout, TimeUnit.MILLISECONDS)
|
||||
// interrupt works as expected.
|
||||
//----------------------------------------------------------------
|
||||
try {
|
||||
List<String> childArgs = new ArrayList<String>(javaChildArgs);
|
||||
childArgs.add("sleep");
|
||||
final Process p = new ProcessBuilder(childArgs).start();
|
||||
final long start = System.nanoTime();
|
||||
|
||||
final Thread thread = new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
try {
|
||||
p.waitFor(10000, TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
return;
|
||||
}
|
||||
fail("waitFor() wasn't interrupted");
|
||||
} catch (Throwable t) { unexpected(t); }}};
|
||||
|
||||
thread.start();
|
||||
Thread.sleep(1000);
|
||||
thread.interrupt();
|
||||
p.destroy();
|
||||
} catch (Throwable t) { unexpected(t); }
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// Check the default implementation for
|
||||
// Process.waitFor(long, TimeUnit)
|
||||
//----------------------------------------------------------------
|
||||
try {
|
||||
List<String> childArgs = new ArrayList<String>(javaChildArgs);
|
||||
childArgs.add("sleep");
|
||||
final Process proc = new ProcessBuilder(childArgs).start();
|
||||
DelegatingProcess p = new DelegatingProcess(proc);
|
||||
long start = System.nanoTime();
|
||||
|
||||
p.waitFor(1000, TimeUnit.MILLISECONDS);
|
||||
|
||||
long end = System.nanoTime();
|
||||
if ((end - start) < 500000000)
|
||||
fail("Test failed: waitFor didn't take long enough");
|
||||
|
||||
p.destroy();
|
||||
|
||||
start = System.nanoTime();
|
||||
p.waitFor(1000, TimeUnit.MILLISECONDS);
|
||||
end = System.nanoTime();
|
||||
// allow for the less accurate default implementation
|
||||
if ((end - start) > 200000000)
|
||||
fail("Test failed: waitFor took too long on a dead process.");
|
||||
} catch (Throwable t) { unexpected(t); }
|
||||
}
|
||||
|
||||
static void closeStreams(Process p) {
|
||||
|
|
172
jdk/test/java/lang/ProcessBuilder/DestroyTest.java
Normal file
172
jdk/test/java/lang/ProcessBuilder/DestroyTest.java
Normal file
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4244896
|
||||
* @summary Test for the various platform specific implementations of
|
||||
* destroyForcibly.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
abstract class ProcessTest implements Runnable {
|
||||
ProcessBuilder bldr;
|
||||
Process p;
|
||||
|
||||
public Process killProc(boolean force) throws Exception {
|
||||
if (force) {
|
||||
p.destroyForcibly();
|
||||
} else {
|
||||
p.destroy();
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
public boolean isAlive() {
|
||||
return p.isAlive();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
String line;
|
||||
BufferedReader is =
|
||||
new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
while ((line = is.readLine()) != null)
|
||||
System.err.println("ProcessTrap: " + line);
|
||||
} catch(IOException e) {
|
||||
if (!e.getMessage().matches("[Ss]tream [Cc]losed")) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void runTest() throws Exception;
|
||||
}
|
||||
|
||||
class UnixTest extends ProcessTest {
|
||||
public UnixTest(File script) throws IOException {
|
||||
script.deleteOnExit();
|
||||
createScript(script);
|
||||
bldr = new ProcessBuilder(script.getCanonicalPath());
|
||||
bldr.redirectErrorStream(true);
|
||||
bldr.directory(new File("."));
|
||||
p = bldr.start();
|
||||
}
|
||||
|
||||
void createScript(File processTrapScript) throws IOException {
|
||||
processTrapScript.deleteOnExit();
|
||||
FileWriter fstream = new FileWriter(processTrapScript);
|
||||
try (BufferedWriter out = new BufferedWriter(fstream)) {
|
||||
out.write("#!/bin/bash\n" +
|
||||
"echo \\\"ProcessTrap.sh started: trapping SIGTERM/SIGINT\\\"\n" +
|
||||
"trap bashtrap SIGTERM SIGINT\n" +
|
||||
"bashtrap()\n" +
|
||||
"{\n" +
|
||||
" echo \\\"SIGTERM/SIGINT detected!\\\"\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"while :\n" +
|
||||
"do\n" +
|
||||
" sleep 1;\n" +
|
||||
"done\n");
|
||||
}
|
||||
processTrapScript.setExecutable(true, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runTest() throws Exception {
|
||||
killProc(false);
|
||||
Thread.sleep(1000);
|
||||
if (!p.isAlive())
|
||||
throw new RuntimeException("Process terminated prematurely.");
|
||||
killProc(true).waitFor();
|
||||
if (p.isAlive())
|
||||
throw new RuntimeException("Problem terminating the process.");
|
||||
}
|
||||
}
|
||||
|
||||
class MacTest extends UnixTest {
|
||||
public MacTest(File script) throws IOException {
|
||||
super(script);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runTest() throws Exception {
|
||||
// On Mac, it appears that when we close the processes streams
|
||||
// after a destroy() call, the process terminates with a
|
||||
// SIGPIPE even if it was trapping the SIGTERM, so as with
|
||||
// windows, we skip the trap test and go straight to destroyForcibly().
|
||||
killProc(true).waitFor();
|
||||
if (p.isAlive())
|
||||
throw new RuntimeException("Problem terminating the process.");
|
||||
}
|
||||
}
|
||||
|
||||
class WindowsTest extends ProcessTest {
|
||||
public WindowsTest() throws IOException {
|
||||
bldr = new ProcessBuilder("ftp");
|
||||
bldr.redirectErrorStream(true);
|
||||
bldr.directory(new File("."));
|
||||
p = bldr.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runTest() throws Exception {
|
||||
killProc(true).waitFor();
|
||||
}
|
||||
}
|
||||
|
||||
public class DestroyTest {
|
||||
|
||||
public static ProcessTest getTest() throws Exception {
|
||||
String osName = System.getProperty("os.name");
|
||||
if (osName.startsWith("Windows")) {
|
||||
return new WindowsTest();
|
||||
} else if (osName.startsWith("Linux") == true) {
|
||||
return new UnixTest(
|
||||
File.createTempFile("ProcessTrap-", ".sh",null));
|
||||
} else if (osName.startsWith("Mac OS")) {
|
||||
return new MacTest(
|
||||
File.createTempFile("ProcessTrap-", ".sh",null));
|
||||
} else if (osName.equals("SunOS")) {
|
||||
return new UnixTest(
|
||||
File.createTempFile("ProcessTrap-", ".sh",null));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
ProcessTest test = getTest();
|
||||
if (test == null) {
|
||||
throw new RuntimeException("Unrecognised OS");
|
||||
} else {
|
||||
new Thread(test).start();
|
||||
Thread.sleep(1000);
|
||||
test.runTest();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue