34 |
34 |
35 import java.lang.ProcessBuilder.Redirect; |
35 import java.lang.ProcessBuilder.Redirect; |
36 import static java.lang.ProcessBuilder.Redirect.*; |
36 import static java.lang.ProcessBuilder.Redirect.*; |
37 |
37 |
38 import java.io.*; |
38 import java.io.*; |
|
39 import java.lang.reflect.Field; |
39 import java.util.*; |
40 import java.util.*; |
40 import java.util.concurrent.CountDownLatch; |
41 import java.util.concurrent.CountDownLatch; |
41 import java.util.concurrent.TimeUnit; |
42 import java.util.concurrent.TimeUnit; |
42 import java.security.*; |
43 import java.security.*; |
43 import java.util.regex.Pattern; |
44 import java.util.regex.Pattern; |
1936 List<String> childArgs = new ArrayList<String>(javaChildArgs); |
1937 List<String> childArgs = new ArrayList<String>(javaChildArgs); |
1937 childArgs.add("sleep"); |
1938 childArgs.add("sleep"); |
1938 final byte[] bytes = new byte[10]; |
1939 final byte[] bytes = new byte[10]; |
1939 final Process p = new ProcessBuilder(childArgs).start(); |
1940 final Process p = new ProcessBuilder(childArgs).start(); |
1940 final CountDownLatch latch = new CountDownLatch(1); |
1941 final CountDownLatch latch = new CountDownLatch(1); |
|
1942 final InputStream s; |
|
1943 switch (action & 0x1) { |
|
1944 case 0: s = p.getInputStream(); break; |
|
1945 case 1: s = p.getErrorStream(); break; |
|
1946 default: throw new Error(); |
|
1947 } |
1941 final Thread thread = new Thread() { |
1948 final Thread thread = new Thread() { |
1942 public void run() { |
1949 public void run() { |
1943 try { |
1950 try { |
|
1951 int r; |
1944 latch.countDown(); |
1952 latch.countDown(); |
1945 int r; |
1953 switch (action & 0x2) { |
1946 switch (action) { |
1954 case 0: r = s.read(); break; |
1947 case 0: r = p.getInputStream().read(); break; |
1955 case 2: r = s.read(bytes); break; |
1948 case 1: r = p.getErrorStream().read(); break; |
1956 default: throw new Error(); |
1949 case 2: r = p.getInputStream().read(bytes); break; |
|
1950 case 3: r = p.getErrorStream().read(bytes); break; |
|
1951 default: throw new Error(); |
|
1952 } |
1957 } |
1953 equal(-1, r); |
1958 equal(-1, r); |
1954 } catch (Throwable t) { unexpected(t); }}}; |
1959 } catch (Throwable t) { unexpected(t); }}}; |
1955 |
1960 |
1956 thread.start(); |
1961 thread.start(); |
1957 latch.await(); |
1962 latch.await(); |
1958 Thread.sleep(10); |
1963 |
|
1964 String os = System.getProperty("os.name"); |
|
1965 if (os.equalsIgnoreCase("Solaris") || |
|
1966 os.equalsIgnoreCase("SunOS")) |
|
1967 { |
|
1968 final Object deferred; |
|
1969 Class<?> c = s.getClass(); |
|
1970 if (c.getName().equals( |
|
1971 "java.lang.UNIXProcess$DeferredCloseInputStream")) |
|
1972 { |
|
1973 deferred = s; |
|
1974 } else { |
|
1975 Field deferredField = p.getClass(). |
|
1976 getDeclaredField("stdout_inner_stream"); |
|
1977 deferredField.setAccessible(true); |
|
1978 deferred = deferredField.get(p); |
|
1979 } |
|
1980 Field useCountField = deferred.getClass(). |
|
1981 getDeclaredField("useCount"); |
|
1982 useCountField.setAccessible(true); |
|
1983 |
|
1984 while (useCountField.getInt(deferred) <= 0) { |
|
1985 Thread.yield(); |
|
1986 } |
|
1987 } |
1959 p.destroy(); |
1988 p.destroy(); |
1960 thread.join(); |
1989 thread.join(); |
1961 } |
1990 } |
1962 } catch (Throwable t) { unexpected(t); } |
1991 } catch (Throwable t) { unexpected(t); } |
1963 |
1992 |