1 /* 2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 4244896 27 * @summary Test for the various platform specific implementations of 28 * destroyForcibly. 29 */ 30 31 import java.io.*; 32 import java.util.ArrayList; 33 import java.util.concurrent.TimeUnit; 34 35 abstract class ProcessTest implements Runnable { 36 ProcessBuilder bldr; 37 Process p; 38 39 public Process killProc(boolean force) throws Exception { 40 if (force) { 41 p.destroyForcibly(); 42 } else { 43 p.destroy(); 44 } 45 return p; 46 } 47 48 public boolean isAlive() { 49 return p.isAlive(); 50 } 51 52 public void run() { 53 try { 54 String line; 55 BufferedReader is = 56 new BufferedReader(new InputStreamReader(p.getInputStream())); 57 while ((line = is.readLine()) != null) 58 System.err.println("ProcessTrap: " + line); 59 } catch(IOException e) { 60 if (!e.getMessage().matches("[Ss]tream [Cc]losed")) { 61 throw new RuntimeException(e); 62 } 63 } 64 } 65 66 public abstract void runTest() throws Exception; 67 } 68 69 class UnixTest extends ProcessTest { 70 public UnixTest(File script) throws IOException { 71 script.deleteOnExit(); 72 createScript(script); 73 bldr = new ProcessBuilder(script.getCanonicalPath()); 74 bldr.redirectErrorStream(true); 75 bldr.directory(new File(".")); 76 p = bldr.start(); 77 } 78 79 void createScript(File processTrapScript) throws IOException { 80 processTrapScript.deleteOnExit(); 81 FileWriter fstream = new FileWriter(processTrapScript); 82 try (BufferedWriter out = new BufferedWriter(fstream)) { 83 out.write("#!/bin/bash\n" + 84 "echo \\\"ProcessTrap.sh started: trapping SIGTERM/SIGINT\\\"\n" + 85 "trap bashtrap SIGTERM SIGINT\n" + 86 "bashtrap()\n" + 87 "{\n" + 88 " echo \\\"SIGTERM/SIGINT detected!\\\"\n" + 89 "}\n" + 90 "\n" + 91 "while :\n" + 92 "do\n" + 93 " sleep 1;\n" + 94 "done\n"); 95 } 96 processTrapScript.setExecutable(true, true); 97 } 98 99 @Override 100 public void runTest() throws Exception { 101 killProc(false); 102 Thread.sleep(1000); 103 if (!p.isAlive()) 104 throw new RuntimeException("Process terminated prematurely."); 105 killProc(true).waitFor(); 106 if (p.isAlive()) 107 throw new RuntimeException("Problem terminating the process."); 108 } 109 } 110 111 class MacTest extends UnixTest { 112 public MacTest(File script) throws IOException { 113 super(script); 114 } 115 116 @Override 117 public void runTest() throws Exception { 118 // On Mac, it appears that when we close the processes streams 119 // after a destroy() call, the process terminates with a 120 // SIGPIPE even if it was trapping the SIGTERM, so as with 121 // windows, we skip the trap test and go straight to destroyForcibly(). 122 killProc(true).waitFor(); 123 if (p.isAlive()) 124 throw new RuntimeException("Problem terminating the process."); 125 } 126 } 127 128 class WindowsTest extends ProcessTest { 129 public WindowsTest() throws IOException { 130 bldr = new ProcessBuilder("ftp"); 131 bldr.redirectErrorStream(true); 132 bldr.directory(new File(".")); 133 p = bldr.start(); 134 } 135 136 @Override 137 public void runTest() throws Exception { 138 killProc(true).waitFor(); 139 } 140 } 141 142 public class DestroyTest { 143 144 public static ProcessTest getTest() throws Exception { 145 String osName = System.getProperty("os.name"); 146 if (osName.startsWith("Windows")) { 147 return new WindowsTest(); 148 } else if (osName.startsWith("Linux") == true) { 149 return new UnixTest( 150 File.createTempFile("ProcessTrap-", ".sh",null)); 151 } else if (osName.startsWith("Mac OS")) { 152 return new MacTest( 153 File.createTempFile("ProcessTrap-", ".sh",null)); 154 } else if (osName.equals("SunOS")) { 155 return new UnixTest( 156 File.createTempFile("ProcessTrap-", ".sh",null)); 157 } 158 return null; 159 } 160 161 public static void main(String args[]) throws Exception { 162 ProcessTest test = getTest(); 163 if (test == null) { 164 throw new RuntimeException("Unrecognised OS"); 165 } else { 166 new Thread(test).start(); 167 Thread.sleep(1000); 168 test.runTest(); 169 } 170 } 171 } 172