Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
7c0ebe7e
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
7c0ebe7e
编写于
6月 26, 2012
作者:
R
robm
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
4244896: (process) Provide System.getPid(), System.killProcess(String pid)
Reviewed-by: alanb
上级
c0fa4bb4
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
598 addition
and
26 deletion
+598
-26
src/share/classes/java/lang/Process.java
src/share/classes/java/lang/Process.java
+95
-7
src/solaris/classes/java/lang/UNIXProcess.java.bsd
src/solaris/classes/java/lang/UNIXProcess.java.bsd
+38
-4
src/solaris/classes/java/lang/UNIXProcess.java.linux
src/solaris/classes/java/lang/UNIXProcess.java.linux
+38
-4
src/solaris/classes/java/lang/UNIXProcess.java.solaris
src/solaris/classes/java/lang/UNIXProcess.java.solaris
+38
-4
src/solaris/native/java/lang/UNIXProcess_md.c
src/solaris/native/java/lang/UNIXProcess_md.c
+7
-3
src/windows/classes/java/lang/ProcessImpl.java
src/windows/classes/java/lang/ProcessImpl.java
+35
-1
src/windows/native/java/lang/ProcessImpl_md.c
src/windows/native/java/lang/ProcessImpl_md.c
+29
-2
test/java/lang/ProcessBuilder/Basic.java
test/java/lang/ProcessBuilder/Basic.java
+146
-1
test/java/lang/ProcessBuilder/DestroyTest.java
test/java/lang/ProcessBuilder/DestroyTest.java
+172
-0
未找到文件。
src/share/classes/java/lang/Process.java
浏览文件 @
7c0ebe7e
/*
/*
* Copyright (c) 1995, 20
08
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 20
12
, 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
...
@@ -26,6 +26,7 @@
...
@@ -26,6 +26,7 @@
package
java.lang
;
package
java.lang
;
import
java.io.*
;
import
java.io.*
;
import
java.util.concurrent.TimeUnit
;
/**
/**
* The {@link ProcessBuilder#start()} and
* The {@link ProcessBuilder#start()} and
...
@@ -91,7 +92,7 @@ public abstract class Process {
...
@@ -91,7 +92,7 @@ public abstract class Process {
* @return the output stream connected to the normal input of the
* @return the output stream connected to the normal input of the
* subprocess
* subprocess
*/
*/
abstract
public
OutputStream
getOutputStream
();
public
abstract
OutputStream
getOutputStream
();
/**
/**
* Returns the input stream connected to the normal output of the
* Returns the input stream connected to the normal output of the
...
@@ -117,7 +118,7 @@ public abstract class Process {
...
@@ -117,7 +118,7 @@ public abstract class Process {
* @return the input stream connected to the normal output of the
* @return the input stream connected to the normal output of the
* subprocess
* subprocess
*/
*/
abstract
public
InputStream
getInputStream
();
public
abstract
InputStream
getInputStream
();
/**
/**
* Returns the input stream connected to the error output of the
* Returns the input stream connected to the error output of the
...
@@ -138,7 +139,7 @@ public abstract class Process {
...
@@ -138,7 +139,7 @@ public abstract class Process {
* @return the input stream connected to the error output of
* @return the input stream connected to the error output of
* the subprocess
* the subprocess
*/
*/
abstract
public
InputStream
getErrorStream
();
public
abstract
InputStream
getErrorStream
();
/**
/**
* Causes the current thread to wait, if necessary, until the
* Causes the current thread to wait, if necessary, until the
...
@@ -156,7 +157,51 @@ public abstract class Process {
...
@@ -156,7 +157,51 @@ public abstract class Process {
* thread while it is waiting, then the wait is ended and
* thread while it is waiting, then the wait is ended and
* an {@link InterruptedException} is thrown.
* an {@link InterruptedException} is thrown.
*/
*/
abstract
public
int
waitFor
()
throws
InterruptedException
;
public
abstract
int
waitFor
()
throws
InterruptedException
;
/**
* Causes the current thread to wait, if necessary, until the
* subprocess represented by this {@code Process} object has
* terminated, or the specified waiting time elapses.
*
* <p>If the subprocess has already terminated then this method returns
* immediately with the value {@code true}. If the process has not
* terminated and the timeout value is less than, or equal to, zero, then
* this method returns immediately with the value {@code false}.
*
* <p>The default implementation of this methods polls the {@code exitValue}
* to check if the process has terminated. Concrete implementations of this
* class are strongly encouraged to override this method with a more
* efficient implementation.
*
* @param timeout the maximum time to wait
* @param unit the time unit of the {@code timeout} argument
* @return {@code true} if the subprocess has exited and {@code false} if
* the waiting time elapsed before the subprocess has exited.
* @throws InterruptedException if the current thread is interrupted
* while waiting.
* @throws NullPointerException if unit is null
* @since 1.8
*/
public
boolean
waitFor
(
long
timeout
,
TimeUnit
unit
)
throws
InterruptedException
{
long
startTime
=
System
.
nanoTime
();
long
rem
=
unit
.
toNanos
(
timeout
);
do
{
try
{
exitValue
();
return
true
;
}
catch
(
IllegalThreadStateException
ex
)
{
if
(
rem
>
0
)
Thread
.
sleep
(
Math
.
min
(
TimeUnit
.
NANOSECONDS
.
toMillis
(
rem
)
+
1
,
100
));
}
rem
=
unit
.
toNanos
(
timeout
)
-
(
System
.
nanoTime
()
-
startTime
);
}
while
(
rem
>
0
);
return
false
;
}
/**
/**
* Returns the exit value for the subprocess.
* Returns the exit value for the subprocess.
...
@@ -167,11 +212,54 @@ public abstract class Process {
...
@@ -167,11 +212,54 @@ public abstract class Process {
* @throws IllegalThreadStateException if the subprocess represented
* @throws IllegalThreadStateException if the subprocess represented
* by this {@code Process} object has not yet terminated
* by this {@code Process} object has not yet terminated
*/
*/
abstract
public
int
exitValue
();
public
abstract
int
exitValue
();
/**
* Kills the subprocess. Whether the subprocess represented by this
* {@code Process} object is forcibly terminated or not is
* implementation dependent.
*/
public
abstract
void
destroy
();
/**
/**
* Kills the subprocess. The subprocess represented by this
* Kills the subprocess. The subprocess represented by this
* {@code Process} object is forcibly terminated.
* {@code Process} object is forcibly terminated.
*
* <p>The default implementation of this method invokes {@link #destroy}
* and so may not forcibly terminate the process. Concrete implementations
* of this class are strongly encouraged to override this method with a
* compliant implementation. Invoking this method on {@code Process}
* objects returned by {@link ProcessBuilder#start} and
* {@link Runtime#exec} will forcibly terminate the process.
*
* <p>Note: The subprocess may not terminate immediately.
* i.e. {@code isAlive()} may return true for a brief period
* after {@code destroyForcibly()} is called. This method
* may be chained to {@code waitFor()} if needed.
*
* @return the {@code Process} object representing the
* subprocess to be forcibly destroyed.
* @since 1.8
*/
public
Process
destroyForcibly
()
{
destroy
();
return
this
;
}
/**
* Tests whether the subprocess represented by this {@code Process} is
* alive.
*
* @return {@code true} if the subprocess represented by this
* {@code Process} object has not yet terminated.
* @since 1.8
*/
*/
abstract
public
void
destroy
();
public
boolean
isAlive
()
{
try
{
exitValue
();
return
false
;
}
catch
(
IllegalThreadStateException
e
)
{
return
true
;
}
}
}
}
src/solaris/classes/java/lang/UNIXProcess.java.bsd
浏览文件 @
7c0ebe7e
/*
/*
*
Copyright
(
c
)
1995
,
201
0
,
Oracle
and
/
or
its
affiliates
.
All
rights
reserved
.
*
Copyright
(
c
)
1995
,
201
2
,
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
...
@@ -38,6 +38,7 @@ import java.util.Arrays;
...
@@ -38,6 +38,7 @@ import java.util.Arrays;
import
java
.
util
.
concurrent
.
Executors
;
import
java
.
util
.
concurrent
.
Executors
;
import
java
.
util
.
concurrent
.
Executor
;
import
java
.
util
.
concurrent
.
Executor
;
import
java
.
util
.
concurrent
.
ThreadFactory
;
import
java
.
util
.
concurrent
.
ThreadFactory
;
import
java
.
util
.
concurrent
.
TimeUnit
;
import
java
.
security
.
AccessController
;
import
java
.
security
.
AccessController
;
import
static
java
.
security
.
AccessController
.
doPrivileged
;
import
static
java
.
security
.
AccessController
.
doPrivileged
;
import
java
.
security
.
PrivilegedAction
;
import
java
.
security
.
PrivilegedAction
;
...
@@ -211,6 +212,24 @@ final class UNIXProcess extends Process {
...
@@ -211,6 +212,24 @@ final class UNIXProcess extends Process {
}
}
return
exitcode
;
return
exitcode
;
}
}
@
Override
public
synchronized
boolean
waitFor
(
long
timeout
,
TimeUnit
unit
)
throws
InterruptedException
{
if
(
hasExited
)
return
true
;
if
(
timeout
<=
0
)
return
false
;
long
timeoutAsNanos
=
unit
.
toNanos
(
timeout
);
long
startTime
=
System
.
nanoTime
();
long
rem
=
timeoutAsNanos
;
while
(
!hasExited && (rem > 0)) {
wait
(
Math
.
max
(
TimeUnit
.
NANOSECONDS
.
toMillis
(
rem
),
1
));
rem
=
timeoutAsNanos
-
(
System
.
nanoTime
()
-
startTime
);
}
return
hasExited
;
}
public
synchronized
int
exitValue
()
{
public
synchronized
int
exitValue
()
{
if
(
!hasExited) {
if
(
!hasExited) {
...
@@ -219,8 +238,8 @@ final class UNIXProcess extends Process {
...
@@ -219,8 +238,8 @@ final class UNIXProcess extends Process {
return
exitcode
;
return
exitcode
;
}
}
private
static
native
void
destroyProcess
(
int
pid
);
private
static
native
void
destroyProcess
(
int
pid
,
boolean
force
);
p
ublic
void
destroy
(
)
{
p
rivate
void
destroy
(
boolean
force
)
{
//
There
is
a
risk
that
pid
will
be
recycled
,
causing
us
to
//
There
is
a
risk
that
pid
will
be
recycled
,
causing
us
to
//
kill
the
wrong
process
! So we only terminate processes
//
kill
the
wrong
process
! So we only terminate processes
//
that
appear
to
still
be
running
.
Even
with
this
check
,
//
that
appear
to
still
be
running
.
Even
with
this
check
,
...
@@ -229,13 +248,28 @@ final class UNIXProcess extends Process {
...
@@ -229,13 +248,28 @@ final class UNIXProcess extends Process {
//
soon
,
so
this
is
quite
safe
.
//
soon
,
so
this
is
quite
safe
.
synchronized
(
this
)
{
synchronized
(
this
)
{
if
(
!hasExited)
if
(
!hasExited)
destroyProcess
(
pid
);
destroyProcess
(
pid
,
force
);
}
}
try
{
stdin
.
close
();
}
catch
(
IOException
ignored
)
{}
try
{
stdin
.
close
();
}
catch
(
IOException
ignored
)
{}
try
{
stdout
.
close
();
}
catch
(
IOException
ignored
)
{}
try
{
stdout
.
close
();
}
catch
(
IOException
ignored
)
{}
try
{
stderr
.
close
();
}
catch
(
IOException
ignored
)
{}
try
{
stderr
.
close
();
}
catch
(
IOException
ignored
)
{}
}
}
public
void
destroy
()
{
destroy
(
false
);
}
@
Override
public
Process
destroyForcibly
()
{
destroy
(
true
);
return
this
;
}
@
Override
public
synchronized
boolean
isAlive
()
{
return
!hasExited;
}
/*
This
routine
initializes
JNI
field
offsets
for
the
class
*/
/*
This
routine
initializes
JNI
field
offsets
for
the
class
*/
private
static
native
void
initIDs
();
private
static
native
void
initIDs
();
...
...
src/solaris/classes/java/lang/UNIXProcess.java.linux
浏览文件 @
7c0ebe7e
/*
/*
*
Copyright
(
c
)
1995
,
201
0
,
Oracle
and
/
or
its
affiliates
.
All
rights
reserved
.
*
Copyright
(
c
)
1995
,
201
2
,
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
...
@@ -38,6 +38,7 @@ import java.util.Arrays;
...
@@ -38,6 +38,7 @@ import java.util.Arrays;
import
java
.
util
.
concurrent
.
Executors
;
import
java
.
util
.
concurrent
.
Executors
;
import
java
.
util
.
concurrent
.
Executor
;
import
java
.
util
.
concurrent
.
Executor
;
import
java
.
util
.
concurrent
.
ThreadFactory
;
import
java
.
util
.
concurrent
.
ThreadFactory
;
import
java
.
util
.
concurrent
.
TimeUnit
;
import
java
.
security
.
AccessController
;
import
java
.
security
.
AccessController
;
import
static
java
.
security
.
AccessController
.
doPrivileged
;
import
static
java
.
security
.
AccessController
.
doPrivileged
;
import
java
.
security
.
PrivilegedAction
;
import
java
.
security
.
PrivilegedAction
;
...
@@ -212,6 +213,24 @@ final class UNIXProcess extends Process {
...
@@ -212,6 +213,24 @@ final class UNIXProcess extends Process {
return
exitcode
;
return
exitcode
;
}
}
@
Override
public
synchronized
boolean
waitFor
(
long
timeout
,
TimeUnit
unit
)
throws
InterruptedException
{
if
(
hasExited
)
return
true
;
if
(
timeout
<=
0
)
return
false
;
long
timeoutAsNanos
=
unit
.
toNanos
(
timeout
);
long
startTime
=
System
.
nanoTime
();
long
rem
=
timeoutAsNanos
;
while
(
!hasExited && (rem > 0)) {
wait
(
Math
.
max
(
TimeUnit
.
NANOSECONDS
.
toMillis
(
rem
),
1
));
rem
=
timeoutAsNanos
-
(
System
.
nanoTime
()
-
startTime
);
}
return
hasExited
;
}
public
synchronized
int
exitValue
()
{
public
synchronized
int
exitValue
()
{
if
(
!hasExited) {
if
(
!hasExited) {
throw
new
IllegalThreadStateException
(
"process hasn't exited"
);
throw
new
IllegalThreadStateException
(
"process hasn't exited"
);
...
@@ -219,8 +238,8 @@ final class UNIXProcess extends Process {
...
@@ -219,8 +238,8 @@ final class UNIXProcess extends Process {
return
exitcode
;
return
exitcode
;
}
}
private
static
native
void
destroyProcess
(
int
pid
);
private
static
native
void
destroyProcess
(
int
pid
,
boolean
force
);
p
ublic
void
destroy
(
)
{
p
rivate
void
destroy
(
boolean
force
)
{
//
There
is
a
risk
that
pid
will
be
recycled
,
causing
us
to
//
There
is
a
risk
that
pid
will
be
recycled
,
causing
us
to
//
kill
the
wrong
process
! So we only terminate processes
//
kill
the
wrong
process
! So we only terminate processes
//
that
appear
to
still
be
running
.
Even
with
this
check
,
//
that
appear
to
still
be
running
.
Even
with
this
check
,
...
@@ -229,13 +248,28 @@ final class UNIXProcess extends Process {
...
@@ -229,13 +248,28 @@ final class UNIXProcess extends Process {
//
soon
,
so
this
is
quite
safe
.
//
soon
,
so
this
is
quite
safe
.
synchronized
(
this
)
{
synchronized
(
this
)
{
if
(
!hasExited)
if
(
!hasExited)
destroyProcess
(
pid
);
destroyProcess
(
pid
,
force
);
}
}
try
{
stdin
.
close
();
}
catch
(
IOException
ignored
)
{}
try
{
stdin
.
close
();
}
catch
(
IOException
ignored
)
{}
try
{
stdout
.
close
();
}
catch
(
IOException
ignored
)
{}
try
{
stdout
.
close
();
}
catch
(
IOException
ignored
)
{}
try
{
stderr
.
close
();
}
catch
(
IOException
ignored
)
{}
try
{
stderr
.
close
();
}
catch
(
IOException
ignored
)
{}
}
}
public
void
destroy
()
{
destroy
(
false
);
}
@
Override
public
Process
destroyForcibly
()
{
destroy
(
true
);
return
this
;
}
@
Override
public
synchronized
boolean
isAlive
()
{
return
!hasExited;
}
/*
This
routine
initializes
JNI
field
offsets
for
the
class
*/
/*
This
routine
initializes
JNI
field
offsets
for
the
class
*/
private
static
native
void
initIDs
();
private
static
native
void
initIDs
();
...
...
src/solaris/classes/java/lang/UNIXProcess.java.solaris
浏览文件 @
7c0ebe7e
/*
/*
*
Copyright
(
c
)
1995
,
201
0
,
Oracle
and
/
or
its
affiliates
.
All
rights
reserved
.
*
Copyright
(
c
)
1995
,
201
2
,
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
...
@@ -26,6 +26,7 @@
...
@@ -26,6 +26,7 @@
package
java
.
lang
;
package
java
.
lang
;
import
java
.
io
.*;
import
java
.
io
.*;
import
java
.
util
.
concurrent
.
TimeUnit
;
/*
java
.
lang
.
Process
subclass
in
the
UNIX
environment
.
/*
java
.
lang
.
Process
subclass
in
the
UNIX
environment
.
*
*
...
@@ -158,6 +159,24 @@ final class UNIXProcess extends Process {
...
@@ -158,6 +159,24 @@ final class UNIXProcess extends Process {
return exitcode;
return exitcode;
}
}
@Override
public synchronized boolean waitFor(long timeout, TimeUnit unit)
throws InterruptedException
{
if (hasExited) return true;
if (timeout <= 0) return false;
long timeoutAsNanos = unit.toNanos(timeout);
long startTime = System.nanoTime();
long rem = timeoutAsNanos;
while (!hasExited && (rem > 0)) {
wait(Math.max(TimeUnit.NANOSECONDS.toMillis(rem), 1));
rem = timeoutAsNanos - (System.nanoTime() - startTime);
}
return hasExited;
}
public synchronized int exitValue() {
public synchronized int exitValue() {
if (!hasExited) {
if (!hasExited) {
throw new IllegalThreadStateException("process hasn'
t
exited
");
throw new IllegalThreadStateException("process hasn'
t
exited
");
...
@@ -165,8 +184,8 @@ final class UNIXProcess extends Process {
...
@@ -165,8 +184,8 @@ final class UNIXProcess extends Process {
return exitcode;
return exitcode;
}
}
private static native void destroyProcess(int pid);
private static native void destroyProcess(int pid
, boolean force
);
p
ublic synchronized void destroy(
) {
p
rivate synchronized void destroy(boolean force
) {
// There is a risk that pid will be recycled, causing us to
// There is a risk that pid will be recycled, causing us to
// kill the wrong process! So we only terminate processes
// kill the wrong process! So we only terminate processes
// that appear to still be running. Even with this check,
// that appear to still be running. Even with this check,
...
@@ -174,7 +193,7 @@ final class UNIXProcess extends Process {
...
@@ -174,7 +193,7 @@ final class UNIXProcess extends Process {
// is very small, and OSes try hard to not recycle pids too
// is very small, and OSes try hard to not recycle pids too
// soon, so this is quite safe.
// soon, so this is quite safe.
if (!hasExited)
if (!hasExited)
destroyProcess(pid);
destroyProcess(pid
, force
);
try {
try {
stdin_stream.close();
stdin_stream.close();
if (stdout_inner_stream != null)
if (stdout_inner_stream != null)
...
@@ -187,6 +206,21 @@ final class UNIXProcess extends Process {
...
@@ -187,6 +206,21 @@ final class UNIXProcess extends Process {
}
}
}
}
public void destroy() {
destroy(false);
}
@Override
public Process destroyForcibly() {
destroy(true);
return this;
}
@Override
public synchronized boolean isAlive() {
return !hasExited;
}
// A FileInputStream that supports the deferment of the actual close
// A FileInputStream that supports the deferment of the actual close
// operation until the last pending I/O operation on the stream has
// operation until the last pending I/O operation on the stream has
// finished. This is required on Solaris because we must close the stdin
// finished. This is required on Solaris because we must close the stdin
...
...
src/solaris/native/java/lang/UNIXProcess_md.c
浏览文件 @
7c0ebe7e
/*
/*
* Copyright (c) 1995, 20
08
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 20
12
, 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
...
@@ -955,7 +955,11 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env,
...
@@ -955,7 +955,11 @@ Java_java_lang_UNIXProcess_forkAndExec(JNIEnv *env,
}
}
JNIEXPORT
void
JNICALL
JNIEXPORT
void
JNICALL
Java_java_lang_UNIXProcess_destroyProcess
(
JNIEnv
*
env
,
jobject
junk
,
jint
pid
)
Java_java_lang_UNIXProcess_destroyProcess
(
JNIEnv
*
env
,
jobject
junk
,
jint
pid
,
jboolean
force
)
{
{
kill
(
pid
,
SIGTERM
);
int
sig
=
(
force
==
JNI_TRUE
)
?
SIGKILL
:
SIGTERM
;
kill
(
pid
,
sig
);
}
}
src/windows/classes/java/lang/ProcessImpl.java
浏览文件 @
7c0ebe7e
/*
/*
* Copyright (c) 1995, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 201
2
, 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
...
@@ -37,6 +37,7 @@ import java.io.BufferedOutputStream;
...
@@ -37,6 +37,7 @@ import java.io.BufferedOutputStream;
import
java.lang.ProcessBuilder.Redirect
;
import
java.lang.ProcessBuilder.Redirect
;
import
java.security.AccessController
;
import
java.security.AccessController
;
import
java.security.PrivilegedAction
;
import
java.security.PrivilegedAction
;
import
java.util.concurrent.TimeUnit
;
/* 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.
...
@@ -254,11 +255,44 @@ final class ProcessImpl extends Process {
...
@@ -254,11 +255,44 @@ final class ProcessImpl extends Process {
throw
new
InterruptedException
();
throw
new
InterruptedException
();
return
exitValue
();
return
exitValue
();
}
}
private
static
native
void
waitForInterruptibly
(
long
handle
);
private
static
native
void
waitForInterruptibly
(
long
handle
);
@Override
public
boolean
waitFor
(
long
timeout
,
TimeUnit
unit
)
throws
InterruptedException
{
if
(
getExitCodeProcess
(
handle
)
!=
STILL_ACTIVE
)
return
true
;
if
(
timeout
<=
0
)
return
false
;
long
msTimeout
=
unit
.
toMillis
(
timeout
);
waitForTimeoutInterruptibly
(
handle
,
msTimeout
);
if
(
Thread
.
interrupted
())
throw
new
InterruptedException
();
return
(
getExitCodeProcess
(
handle
)
!=
STILL_ACTIVE
);
}
private
static
native
void
waitForTimeoutInterruptibly
(
long
handle
,
long
timeout
);
public
void
destroy
()
{
terminateProcess
(
handle
);
}
public
void
destroy
()
{
terminateProcess
(
handle
);
}
@Override
public
Process
destroyForcibly
()
{
destroy
();
return
this
;
}
private
static
native
void
terminateProcess
(
long
handle
);
private
static
native
void
terminateProcess
(
long
handle
);
@Override
public
boolean
isAlive
()
{
return
isProcessAlive
(
handle
);
}
private
static
native
boolean
isProcessAlive
(
long
handle
);
/**
/**
* Create a process using the win32 function CreateProcess.
* Create a process using the win32 function CreateProcess.
*
*
...
...
src/windows/native/java/lang/ProcessImpl_md.c
浏览文件 @
7c0ebe7e
/*
/*
* Copyright (c) 1997, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
2
, 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
...
@@ -299,17 +299,44 @@ Java_java_lang_ProcessImpl_waitForInterruptibly(JNIEnv *env, jclass ignored, jlo
...
@@ -299,17 +299,44 @@ Java_java_lang_ProcessImpl_waitForInterruptibly(JNIEnv *env, jclass ignored, jlo
if
(
WaitForMultipleObjects
(
sizeof
(
events
)
/
sizeof
(
events
[
0
]),
events
,
if
(
WaitForMultipleObjects
(
sizeof
(
events
)
/
sizeof
(
events
[
0
]),
events
,
FALSE
,
/* Wait for ANY event */
FALSE
,
/* Wait for ANY event */
INFINITE
)
/* Wait forever */
INFINITE
)
/* Wait forever */
==
WAIT_FAILED
)
==
WAIT_FAILED
)
win32Error
(
env
,
"WaitForMultipleObjects"
);
win32Error
(
env
,
"WaitForMultipleObjects"
);
}
}
JNIEXPORT
void
JNICALL
Java_java_lang_ProcessImpl_waitForTimeoutInterruptibly
(
JNIEnv
*
env
,
jclass
ignored
,
jlong
handle
,
jlong
timeout
)
{
HANDLE
events
[
2
];
DWORD
dwTimeout
=
(
DWORD
)
timeout
;
DWORD
result
;
events
[
0
]
=
(
HANDLE
)
handle
;
events
[
1
]
=
JVM_GetThreadInterruptEvent
();
result
=
WaitForMultipleObjects
(
sizeof
(
events
)
/
sizeof
(
events
[
0
]),
events
,
FALSE
,
/* Wait for ANY event */
dwTimeout
);
/* Wait for dwTimeout */
if
(
result
==
WAIT_FAILED
)
win32Error
(
env
,
"WaitForMultipleObjects"
);
}
JNIEXPORT
void
JNICALL
JNIEXPORT
void
JNICALL
Java_java_lang_ProcessImpl_terminateProcess
(
JNIEnv
*
env
,
jclass
ignored
,
jlong
handle
)
Java_java_lang_ProcessImpl_terminateProcess
(
JNIEnv
*
env
,
jclass
ignored
,
jlong
handle
)
{
{
TerminateProcess
((
HANDLE
)
handle
,
1
);
TerminateProcess
((
HANDLE
)
handle
,
1
);
}
}
JNIEXPORT
jboolean
JNICALL
Java_java_lang_ProcessImpl_isProcessAlive
(
JNIEnv
*
env
,
jclass
ignored
,
jlong
handle
)
{
DWORD
dwExitStatus
;
GetExitCodeProcess
(
handle
,
&
dwExitStatus
);
return
dwExitStatus
==
STILL_ACTIVE
;
}
JNIEXPORT
jboolean
JNICALL
JNIEXPORT
jboolean
JNICALL
Java_java_lang_ProcessImpl_closeHandle
(
JNIEnv
*
env
,
jclass
ignored
,
jlong
handle
)
Java_java_lang_ProcessImpl_closeHandle
(
JNIEnv
*
env
,
jclass
ignored
,
jlong
handle
)
{
{
...
...
test/java/lang/ProcessBuilder/Basic.java
浏览文件 @
7c0ebe7e
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
* @bug 4199068 4738465 4937983 4930681 4926230 4931433 4932663 4986689
* @bug 4199068 4738465 4937983 4930681 4926230 4931433 4932663 4986689
* 5026830 5023243 5070673 4052517 4811767 6192449 6397034 6413313
* 5026830 5023243 5070673 4052517 4811767 6192449 6397034 6413313
* 6464154 6523983 6206031 4960438 6631352 6631966 6850957 6850958
* 6464154 6523983 6206031 4960438 6631352 6631966 6850957 6850958
* 4947220 7018606 7034570
* 4947220 7018606 7034570
4244896
* @summary Basic tests for Process and Environment Variable code
* @summary Basic tests for Process and Environment Variable code
* @run main/othervm/timeout=300 Basic
* @run main/othervm/timeout=300 Basic
* @author Martin Buchholz
* @author Martin Buchholz
...
@@ -38,6 +38,7 @@ import static java.lang.ProcessBuilder.Redirect.*;
...
@@ -38,6 +38,7 @@ import static java.lang.ProcessBuilder.Redirect.*;
import
java.io.*
;
import
java.io.*
;
import
java.util.*
;
import
java.util.*
;
import
java.util.concurrent.CountDownLatch
;
import
java.util.concurrent.CountDownLatch
;
import
java.util.concurrent.TimeUnit
;
import
java.security.*
;
import
java.security.*
;
import
java.util.regex.Pattern
;
import
java.util.regex.Pattern
;
import
java.util.regex.Matcher
;
import
java.util.regex.Matcher
;
...
@@ -636,6 +637,44 @@ public class Basic {
...
@@ -636,6 +637,44 @@ public class Basic {
static
boolean
is
()
{
return
is
;
}
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
)
{
private
static
boolean
matches
(
String
str
,
String
regex
)
{
return
Pattern
.
compile
(
regex
).
matcher
(
str
).
find
();
return
Pattern
.
compile
(
regex
).
matcher
(
str
).
find
();
}
}
...
@@ -2090,6 +2129,112 @@ public class Basic {
...
@@ -2090,6 +2129,112 @@ public class Basic {
policy
.
setPermissions
(
new
RuntimePermission
(
"setSecurityManager"
));
policy
.
setPermissions
(
new
RuntimePermission
(
"setSecurityManager"
));
System
.
setSecurityManager
(
null
);
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
)
{
static
void
closeStreams
(
Process
p
)
{
...
...
test/java/lang/ProcessBuilder/DestroyTest.java
0 → 100644
浏览文件 @
7c0ebe7e
/*
* 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
();
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录