59 static final String systemRoot = System.getenv("SystemRoot"); |
59 static final String systemRoot = System.getenv("SystemRoot"); |
60 |
60 |
61 /* used for Mac OS X only */ |
61 /* used for Mac OS X only */ |
62 static final String cfUserTextEncoding = System.getenv("__CF_USER_TEXT_ENCODING"); |
62 static final String cfUserTextEncoding = System.getenv("__CF_USER_TEXT_ENCODING"); |
63 |
63 |
|
64 /* used for AIX only */ |
|
65 static final String libpath = System.getenv("LIBPATH"); |
|
66 |
64 /** |
67 /** |
65 * Returns the number of milliseconds since time given by |
68 * Returns the number of milliseconds since time given by |
66 * startNanoTime, which must have been previously returned from a |
69 * startNanoTime, which must have been previously returned from a |
67 * call to {@link System.nanoTime()}. |
70 * call to {@link System.nanoTime()}. |
68 */ |
71 */ |
85 check(p.getErrorStream() == p.getErrorStream()); |
88 check(p.getErrorStream() == p.getErrorStream()); |
86 Reader r = new InputStreamReader(p.getInputStream(),"UTF-8"); |
89 Reader r = new InputStreamReader(p.getInputStream(),"UTF-8"); |
87 String output = commandOutput(r); |
90 String output = commandOutput(r); |
88 equal(p.waitFor(), 0); |
91 equal(p.waitFor(), 0); |
89 equal(p.exitValue(), 0); |
92 equal(p.exitValue(), 0); |
90 return output; |
93 // The debug/fastdebug versions of the VM may write some warnings to stdout |
|
94 // (i.e. "Warning: Cannot open log file: hotspot.log" if the VM is started |
|
95 // in a directory without write permissions). These warnings will confuse tests |
|
96 // which match the entire output of the child process so better filter them out. |
|
97 return output.replaceAll("Warning:.*\\n", ""); |
91 } |
98 } |
92 |
99 |
93 private static String commandOutput(ProcessBuilder pb) { |
100 private static String commandOutput(ProcessBuilder pb) { |
94 try { |
101 try { |
95 return commandOutput(pb.start()); |
102 return commandOutput(pb.start()); |
586 public static boolean is() { return is; } |
593 public static boolean is() { return is; } |
587 private static final boolean is = |
594 private static final boolean is = |
588 System.getProperty("os.name").startsWith("Windows"); |
595 System.getProperty("os.name").startsWith("Windows"); |
589 } |
596 } |
590 |
597 |
|
598 static class AIX { |
|
599 public static boolean is() { return is; } |
|
600 private static final boolean is = |
|
601 System.getProperty("os.name").equals("AIX"); |
|
602 } |
|
603 |
591 static class Unix { |
604 static class Unix { |
592 public static boolean is() { return is; } |
605 public static boolean is() { return is; } |
593 private static final boolean is = |
606 private static final boolean is = |
594 (! Windows.is() && |
607 (! Windows.is() && |
595 new File("/bin/sh").exists() && |
608 new File("/bin/sh").exists() && |
639 private final static Boolean is = |
652 private final static Boolean is = |
640 (! Windows.is() && isEnglish("LANG") && isEnglish("LC_ALL")); |
653 (! Windows.is() && isEnglish("LANG") && isEnglish("LC_ALL")); |
641 |
654 |
642 private static boolean isEnglish(String envvar) { |
655 private static boolean isEnglish(String envvar) { |
643 String val = getenv(envvar); |
656 String val = getenv(envvar); |
644 return (val == null) || val.matches("en.*"); |
657 return (val == null) || val.matches("en.*") || val.matches("C"); |
645 } |
658 } |
646 |
659 |
647 /** Returns true if we can expect English OS error strings */ |
660 /** Returns true if we can expect English OS error strings */ |
648 static boolean is() { return is; } |
661 static boolean is() { return is; } |
649 } |
662 } |
712 // Check for JAVA_MAIN_CLASS_<pid> |
725 // Check for JAVA_MAIN_CLASS_<pid> |
713 String javaMainClassStr |
726 String javaMainClassStr |
714 = matchAndExtract(cleanedVars, |
727 = matchAndExtract(cleanedVars, |
715 "JAVA_MAIN_CLASS_\\d+=Basic.JavaChild,"); |
728 "JAVA_MAIN_CLASS_\\d+=Basic.JavaChild,"); |
716 return cleanedVars.replace(javaMainClassStr,""); |
729 return cleanedVars.replace(javaMainClassStr,""); |
|
730 } |
|
731 |
|
732 /* Only used for AIX -- |
|
733 * AIX adds the variable AIXTHREAD_GUARDPAGES=0 to the environment. |
|
734 * Remove it from the list of env variables |
|
735 */ |
|
736 private static String removeAixExpectedVars(String vars) { |
|
737 return vars.replace("AIXTHREAD_GUARDPAGES=0,",""); |
717 } |
738 } |
718 |
739 |
719 private static String sortByLinesWindowsly(String text) { |
740 private static String sortByLinesWindowsly(String text) { |
720 String[] lines = text.split("\n"); |
741 String[] lines = text.split("\n"); |
721 Arrays.sort(lines, new WindowsComparator()); |
742 Arrays.sort(lines, new WindowsComparator()); |
1162 //---------------------------------------------------------------- |
1183 //---------------------------------------------------------------- |
1163 try { |
1184 try { |
1164 ProcessBuilder pb = new ProcessBuilder(); |
1185 ProcessBuilder pb = new ProcessBuilder(); |
1165 pb.environment().clear(); |
1186 pb.environment().clear(); |
1166 String expected = Windows.is() ? "SystemRoot="+systemRoot+",": ""; |
1187 String expected = Windows.is() ? "SystemRoot="+systemRoot+",": ""; |
|
1188 expected = AIX.is() ? "LIBPATH="+libpath+",": expected; |
1167 if (Windows.is()) { |
1189 if (Windows.is()) { |
1168 pb.environment().put("SystemRoot", systemRoot); |
1190 pb.environment().put("SystemRoot", systemRoot); |
|
1191 } |
|
1192 if (AIX.is()) { |
|
1193 pb.environment().put("LIBPATH", libpath); |
1169 } |
1194 } |
1170 String result = getenvInChild(pb); |
1195 String result = getenvInChild(pb); |
1171 if (MacOSX.is()) { |
1196 if (MacOSX.is()) { |
1172 result = removeMacExpectedVars(result); |
1197 result = removeMacExpectedVars(result); |
|
1198 } |
|
1199 if (AIX.is()) { |
|
1200 result = removeAixExpectedVars(result); |
1173 } |
1201 } |
1174 equal(result, expected); |
1202 equal(result, expected); |
1175 } catch (Throwable t) { unexpected(t); } |
1203 } catch (Throwable t) { unexpected(t); } |
1176 |
1204 |
1177 //---------------------------------------------------------------- |
1205 //---------------------------------------------------------------- |
1683 } else { |
1711 } else { |
1684 envp = envpOth; |
1712 envp = envpOth; |
1685 } |
1713 } |
1686 Process p = Runtime.getRuntime().exec(cmdp, envp); |
1714 Process p = Runtime.getRuntime().exec(cmdp, envp); |
1687 String expected = Windows.is() ? "=C:=\\,=ExitValue=3,SystemRoot="+systemRoot+"," : "=C:=\\,"; |
1715 String expected = Windows.is() ? "=C:=\\,=ExitValue=3,SystemRoot="+systemRoot+"," : "=C:=\\,"; |
|
1716 expected = AIX.is() ? expected + "LIBPATH="+libpath+",": expected; |
1688 String commandOutput = commandOutput(p); |
1717 String commandOutput = commandOutput(p); |
1689 if (MacOSX.is()) { |
1718 if (MacOSX.is()) { |
1690 commandOutput = removeMacExpectedVars(commandOutput); |
1719 commandOutput = removeMacExpectedVars(commandOutput); |
|
1720 } |
|
1721 if (AIX.is()) { |
|
1722 commandOutput = removeAixExpectedVars(commandOutput); |
1691 } |
1723 } |
1692 equal(commandOutput, expected); |
1724 equal(commandOutput, expected); |
1693 if (Windows.is()) { |
1725 if (Windows.is()) { |
1694 ProcessBuilder pb = new ProcessBuilder(childArgs); |
1726 ProcessBuilder pb = new ProcessBuilder(childArgs); |
1695 pb.environment().clear(); |
1727 pb.environment().clear(); |
1738 Process p = Runtime.getRuntime().exec(cmdp, envp); |
1770 Process p = Runtime.getRuntime().exec(cmdp, envp); |
1739 String commandOutput = commandOutput(p); |
1771 String commandOutput = commandOutput(p); |
1740 if (MacOSX.is()) { |
1772 if (MacOSX.is()) { |
1741 commandOutput = removeMacExpectedVars(commandOutput); |
1773 commandOutput = removeMacExpectedVars(commandOutput); |
1742 } |
1774 } |
|
1775 if (AIX.is()) { |
|
1776 commandOutput = removeAixExpectedVars(commandOutput); |
|
1777 } |
1743 check(commandOutput.equals(Windows.is() |
1778 check(commandOutput.equals(Windows.is() |
1744 ? "LC_ALL=C,SystemRoot="+systemRoot+"," |
1779 ? "LC_ALL=C,SystemRoot="+systemRoot+"," |
1745 : "LC_ALL=C,"), |
1780 : AIX.is() |
|
1781 ? "LC_ALL=C,LIBPATH="+libpath+"," |
|
1782 : "LC_ALL=C,"), |
1746 "Incorrect handling of envstrings containing NULs"); |
1783 "Incorrect handling of envstrings containing NULs"); |
1747 } catch (Throwable t) { unexpected(t); } |
1784 } catch (Throwable t) { unexpected(t); } |
1748 |
1785 |
1749 //---------------------------------------------------------------- |
1786 //---------------------------------------------------------------- |
1750 // Test the redirectErrorStream property |
1787 // Test the redirectErrorStream property |
2017 //---------------------------------------------------------------- |
2054 //---------------------------------------------------------------- |
2018 try { |
2055 try { |
2019 if (Unix.is() |
2056 if (Unix.is() |
2020 && new File("/bin/bash").exists() |
2057 && new File("/bin/bash").exists() |
2021 && new File("/bin/sleep").exists()) { |
2058 && new File("/bin/sleep").exists()) { |
2022 final String[] cmd = { "/bin/bash", "-c", "(/bin/sleep 6666)" }; |
2059 // Notice that we only destroy the process created by us (i.e. |
2023 final String[] cmdkill = { "/bin/bash", "-c", "(/usr/bin/pkill -f \"sleep 6666\")" }; |
2060 // our child) but not our grandchild (i.e. '/bin/sleep'). So |
|
2061 // pay attention that the grandchild doesn't run too long to |
|
2062 // avoid polluting the process space with useless processes. |
|
2063 // Running the grandchild for 60s should be more than enough. |
|
2064 final String[] cmd = { "/bin/bash", "-c", "(/bin/sleep 60)" }; |
|
2065 final String[] cmdkill = { "/bin/bash", "-c", "(/usr/bin/pkill -f \"sleep 60\")" }; |
2024 final ProcessBuilder pb = new ProcessBuilder(cmd); |
2066 final ProcessBuilder pb = new ProcessBuilder(cmd); |
2025 final Process p = pb.start(); |
2067 final Process p = pb.start(); |
2026 final InputStream stdout = p.getInputStream(); |
2068 final InputStream stdout = p.getInputStream(); |
2027 final InputStream stderr = p.getErrorStream(); |
2069 final InputStream stderr = p.getErrorStream(); |
2028 final OutputStream stdin = p.getOutputStream(); |
2070 final OutputStream stdin = p.getOutputStream(); |
2040 catch (Throwable t) { unexpected(t); }}}; |
2082 catch (Throwable t) { unexpected(t); }}}; |
2041 reader.setDaemon(true); |
2083 reader.setDaemon(true); |
2042 reader.start(); |
2084 reader.start(); |
2043 Thread.sleep(100); |
2085 Thread.sleep(100); |
2044 p.destroy(); |
2086 p.destroy(); |
2045 // Subprocess is now dead, but file descriptors remain open. |
|
2046 check(p.waitFor() != 0); |
2087 check(p.waitFor() != 0); |
2047 check(p.exitValue() != 0); |
2088 check(p.exitValue() != 0); |
|
2089 // Subprocess is now dead, but file descriptors remain open. |
|
2090 // Make sure the test will fail if we don't manage to close |
|
2091 // the open streams within 30 seconds. Notice that this time |
|
2092 // must be shorter than the sleep time of the grandchild. |
|
2093 Timer t = new Timer("test/java/lang/ProcessBuilder/Basic.java process reaper", true); |
|
2094 t.schedule(new TimerTask() { |
|
2095 public void run() { |
|
2096 fail("Subprocesses which create subprocesses of " + |
|
2097 "their own caused the parent to hang while " + |
|
2098 "waiting for file descriptors to be closed."); |
|
2099 System.exit(-1); |
|
2100 } |
|
2101 }, 30000); |
2048 stdout.close(); |
2102 stdout.close(); |
2049 stderr.close(); |
2103 stderr.close(); |
2050 stdin.close(); |
2104 stdin.close(); |
2051 new ProcessBuilder(cmdkill).start(); |
2105 new ProcessBuilder(cmdkill).start(); |
|
2106 // All streams successfully closed so we can cancel the timer. |
|
2107 t.cancel(); |
2052 //---------------------------------------------------------- |
2108 //---------------------------------------------------------- |
2053 // There remain unsolved issues with asynchronous close. |
2109 // There remain unsolved issues with asynchronous close. |
2054 // Here's a highly non-portable experiment to demonstrate: |
2110 // Here's a highly non-portable experiment to demonstrate: |
2055 //---------------------------------------------------------- |
2111 //---------------------------------------------------------- |
2056 if (Boolean.getBoolean("wakeupJeff!")) { |
2112 if (Boolean.getBoolean("wakeupJeff!")) { |
2192 if (!p.isAlive() || p.waitFor(0, TimeUnit.MILLISECONDS)) { |
2248 if (!p.isAlive() || p.waitFor(0, TimeUnit.MILLISECONDS)) { |
2193 fail("Test failed: Process exited prematurely"); |
2249 fail("Test failed: Process exited prematurely"); |
2194 } |
2250 } |
2195 long end = System.nanoTime(); |
2251 long end = System.nanoTime(); |
2196 // give waitFor(timeout) a wide berth (100ms) |
2252 // give waitFor(timeout) a wide berth (100ms) |
2197 if ((end - start) > 100000000) |
2253 // Old AIX machines my need a little longer. |
2198 fail("Test failed: waitFor took too long"); |
2254 if ((end - start) > 100000000L * (AIX.is() ? 4 : 1)) |
|
2255 fail("Test failed: waitFor took too long (" + (end - start) + "ns)"); |
2199 |
2256 |
2200 p.destroy(); |
2257 p.destroy(); |
2201 p.waitFor(); |
2258 p.waitFor(); |
2202 |
2259 |
2203 if (p.isAlive() || |
2260 if (p.isAlive() || |
2220 |
2277 |
2221 p.waitFor(1000, TimeUnit.MILLISECONDS); |
2278 p.waitFor(1000, TimeUnit.MILLISECONDS); |
2222 |
2279 |
2223 long end = System.nanoTime(); |
2280 long end = System.nanoTime(); |
2224 if ((end - start) < 500000000) |
2281 if ((end - start) < 500000000) |
2225 fail("Test failed: waitFor didn't take long enough"); |
2282 fail("Test failed: waitFor didn't take long enough (" + (end - start) + "ns)"); |
2226 |
2283 |
2227 p.destroy(); |
2284 p.destroy(); |
2228 |
2285 |
2229 start = System.nanoTime(); |
2286 start = System.nanoTime(); |
2230 p.waitFor(1000, TimeUnit.MILLISECONDS); |
2287 p.waitFor(1000, TimeUnit.MILLISECONDS); |
2231 end = System.nanoTime(); |
2288 end = System.nanoTime(); |
2232 if ((end - start) > 900000000) |
2289 if ((end - start) > 900000000) |
2233 fail("Test failed: waitFor took too long on a dead process."); |
2290 fail("Test failed: waitFor took too long on a dead process. (" + (end - start) + "ns)"); |
2234 } catch (Throwable t) { unexpected(t); } |
2291 } catch (Throwable t) { unexpected(t); } |
2235 |
2292 |
2236 //---------------------------------------------------------------- |
2293 //---------------------------------------------------------------- |
2237 // Check that Process.waitFor(timeout, TimeUnit.MILLISECONDS) |
2294 // Check that Process.waitFor(timeout, TimeUnit.MILLISECONDS) |
2238 // interrupt works as expected, if interrupted while waiting. |
2295 // interrupt works as expected, if interrupted while waiting. |