1999 while (unsafe.tryMonitorEnter(s)) { 2000 unsafe.monitorExit(s); 2001 Thread.sleep(1); 2002 } 2003 } 2004 p.destroy(); 2005 thread.join(); 2006 } 2007 } catch (Throwable t) { unexpected(t); } 2008 2009 //---------------------------------------------------------------- 2010 // Check that subprocesses which create subprocesses of their 2011 // own do not cause parent to hang waiting for file 2012 // descriptors to be closed. 2013 //---------------------------------------------------------------- 2014 try { 2015 if (Unix.is() 2016 && new File("/bin/bash").exists() 2017 && new File("/bin/sleep").exists()) { 2018 final String[] cmd = { "/bin/bash", "-c", "(/bin/sleep 6666)" }; 2019 final ProcessBuilder pb = new ProcessBuilder(cmd); 2020 final Process p = pb.start(); 2021 final InputStream stdout = p.getInputStream(); 2022 final InputStream stderr = p.getErrorStream(); 2023 final OutputStream stdin = p.getOutputStream(); 2024 final Thread reader = new Thread() { 2025 public void run() { 2026 try { stdout.read(); } 2027 catch (IOException e) { 2028 // Check that reader failed because stream was 2029 // asynchronously closed. 2030 // e.printStackTrace(); 2031 if (EnglishUnix.is() && 2032 ! (e.getMessage().matches(".*Bad file.*"))) 2033 unexpected(e); 2034 } 2035 catch (Throwable t) { unexpected(t); }}}; 2036 reader.setDaemon(true); 2037 reader.start(); 2038 Thread.sleep(100); 2039 p.destroy(); 2040 // Subprocess is now dead, but file descriptors remain open. 2041 check(p.waitFor() != 0); 2042 check(p.exitValue() != 0); 2043 stdout.close(); 2044 stderr.close(); 2045 stdin.close(); 2046 //---------------------------------------------------------- 2047 // There remain unsolved issues with asynchronous close. 2048 // Here's a highly non-portable experiment to demonstrate: 2049 //---------------------------------------------------------- 2050 if (Boolean.getBoolean("wakeupJeff!")) { 2051 System.out.println("wakeupJeff!"); 2052 // Initialize signal handler for INTERRUPT_SIGNAL. 2053 new FileInputStream("/bin/sleep").getChannel().close(); 2054 // Send INTERRUPT_SIGNAL to every thread in this java. 2055 String[] wakeupJeff = { 2056 "/bin/bash", "-c", 2057 "/bin/ps --noheaders -Lfp $PPID | " + 2058 "/usr/bin/perl -nale 'print $F[3]' | " + 2059 // INTERRUPT_SIGNAL == 62 on my machine du jour. 2060 "/usr/bin/xargs kill -62" 2061 }; 2062 new ProcessBuilder(wakeupJeff).start().waitFor(); 2063 // If wakeupJeff worked, reader probably got EBADF. 2064 reader.join(); 2065 } | 1999 while (unsafe.tryMonitorEnter(s)) { 2000 unsafe.monitorExit(s); 2001 Thread.sleep(1); 2002 } 2003 } 2004 p.destroy(); 2005 thread.join(); 2006 } 2007 } catch (Throwable t) { unexpected(t); } 2008 2009 //---------------------------------------------------------------- 2010 // Check that subprocesses which create subprocesses of their 2011 // own do not cause parent to hang waiting for file 2012 // descriptors to be closed. 2013 //---------------------------------------------------------------- 2014 try { 2015 if (Unix.is() 2016 && new File("/bin/bash").exists() 2017 && new File("/bin/sleep").exists()) { 2018 final String[] cmd = { "/bin/bash", "-c", "(/bin/sleep 6666)" }; 2019 final String[] cmdkill = { "/bin/bash", "-c", "(/usr/bin/pkill -f \"sleep 6666\")" }; 2020 final ProcessBuilder pb = new ProcessBuilder(cmd); 2021 final Process p = pb.start(); 2022 final InputStream stdout = p.getInputStream(); 2023 final InputStream stderr = p.getErrorStream(); 2024 final OutputStream stdin = p.getOutputStream(); 2025 final Thread reader = new Thread() { 2026 public void run() { 2027 try { stdout.read(); } 2028 catch (IOException e) { 2029 // Check that reader failed because stream was 2030 // asynchronously closed. 2031 // e.printStackTrace(); 2032 if (EnglishUnix.is() && 2033 ! (e.getMessage().matches(".*Bad file.*"))) 2034 unexpected(e); 2035 } 2036 catch (Throwable t) { unexpected(t); }}}; 2037 reader.setDaemon(true); 2038 reader.start(); 2039 Thread.sleep(100); 2040 p.destroy(); 2041 // Subprocess is now dead, but file descriptors remain open. 2042 check(p.waitFor() != 0); 2043 check(p.exitValue() != 0); 2044 stdout.close(); 2045 stderr.close(); 2046 stdin.close(); 2047 new ProcessBuilder(cmdkill).start(); 2048 //---------------------------------------------------------- 2049 // There remain unsolved issues with asynchronous close. 2050 // Here's a highly non-portable experiment to demonstrate: 2051 //---------------------------------------------------------- 2052 if (Boolean.getBoolean("wakeupJeff!")) { 2053 System.out.println("wakeupJeff!"); 2054 // Initialize signal handler for INTERRUPT_SIGNAL. 2055 new FileInputStream("/bin/sleep").getChannel().close(); 2056 // Send INTERRUPT_SIGNAL to every thread in this java. 2057 String[] wakeupJeff = { 2058 "/bin/bash", "-c", 2059 "/bin/ps --noheaders -Lfp $PPID | " + 2060 "/usr/bin/perl -nale 'print $F[3]' | " + 2061 // INTERRUPT_SIGNAL == 62 on my machine du jour. 2062 "/usr/bin/xargs kill -62" 2063 }; 2064 new ProcessBuilder(wakeupJeff).start().waitFor(); 2065 // If wakeupJeff worked, reader probably got EBADF. 2066 reader.join(); 2067 } |