jdk/test/java/lang/ProcessBuilder/Basic.java
changeset 22607 ba232b417248
parent 22288 81efc55fac99
parent 22600 a509464f280f
child 24577 b3bf9c82a050
equal deleted inserted replaced
22585:cb36782f6044 22607:ba232b417248
    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.